Como criar um arquivo chamado como um argumento de linha de comando?

29

Fiquei me perguntando como criar um arquivo nomeado como um sinalizador, por exemplo, se eu quisesse criar uma pasta chamada -a, quais comandos fariam o truque?

Eu tentei mkdir '-a', mkdir \-ae nem funcionou. Estou no Ubuntu.

MEU V
fonte
13
As respostas aqui são todos grandes, mas eu não posso pensar em uma razão não-troll quer fazer isso ...
evilsoup
@evilsoup Algumas pessoas gostam de prefixar pastas para ficarem no topo de uma lista classificada alfanumericamente. Mas é a única razão pela qual consigo pensar, para ser sincero.
Slhck 26/05
@slhck Conheço pelo menos um curso de edição de vídeo em que eles incentivam os alunos a anexar espaços em branco aos diretórios de seus projetos, para que apareçam no topo dos iMacs comuns. Este foi feio e levou a uma escalada hilariante, mas pelo menos não seria potencialmente quebra-sistema ...
evilsoup
3
Principalmente aqui está por interesse acadêmico.
MYV
5
Obrigatória quadrinhos: beesbuzz.biz/d/20110224.php
fofo

Respostas:

49

Chame o comando da seguinte maneira:

mkdir -- -a

Os --meios que as opções terminam depois disso, então as -ainterpretações são literalmente e não como uma opção mkdir. Você encontrará essa sintaxe não apenas em mkdir, mas em qualquer utilitário compatível com POSIX, exceto echoe test. A partir da especificação :

O argumento - deve ser aceito como um delimitador indicando o final das opções. Quaisquer argumentos a seguir devem ser tratados como operandos, mesmo se começarem com o caractere '-'. O argumento - não deve ser usado como uma opção ou como um operando.

O uso --como salvaguarda é recomendado para quase todas as ações em que você lida com nomes de arquivos e deseja garantir que eles não quebrem o comando; por exemplo, ao mover arquivos em um loop, convém chamar o seguinte, para que um arquivo chamado -iisn ' t (in?) corretamente analisado como uma opção:

mv -- "$f" new-"$f"
slhck
fonte
A desvantagem dessa abordagem é precisamente que ela encerra o processamento das opções. Para um exemplo simples de mkdir, isso faz maravilhas; se você realmente precisar de uma opção para seguir o nome do arquivo na linha de comando, ele não funcionará.
um CVn
11
Claro - há uma desvantagem em tudo. Nos casos em que você lida com nomes de arquivos intercalados com opções, a solução de Amos seria a única alternativa sã em que posso pensar, mas isso realmente depende de como a ferramenta analisa as opções.
Slhck 26/05
11
Como o OP fala sobre a criação de um arquivo com um nome "como um argumento de linha de comando" (vamos assumir que significa um nome que começa com um hífen), não acho que seja uma suposição totalmente irracional. Tome cc -o -myfile -Wall -myfile.ccomo um exemplo apenas um pouco artificial. Qualquer editor que se preze deve ser capaz de salvar em um arquivo nomeado -myfile.cse você solicitar, mas o compilador C provavelmente não fará o que você deseja quando receber uma lista dessas opções.
um CVn
11
@Maksim Por exemplo, comandos que requerem uma opção para definir um nome de arquivo de entrada ou saída, como o cccomando que Michael deu acima, que tem a -oopção de especificar o arquivo de saída.
Slhck 26/05
11
O exemplo de loop é por isso que você deve sempre usar algo como for f in ./*; do..., em vez defor f in *; do...
evilsoup
21

A maneira mais simples que deve funcionar com qualquer programa razoável é usar um nome de caminho relativo na frente do -, por exemplo mkdir ./-a, criará um diretório chamado -ano diretório de trabalho atual.

O exemplo mais comum de usar esse "truque" é quando você deseja remover um arquivo que começa com um traço, para que você possa fazê-lo rm ./-a.

Amos Shapira
fonte
3
Obviamente, isso só funciona se você estiver trabalhando com caminhos de arquivo, e não com nenhuma opção arbitrária de linha de comando que seja analisada como string. Mas, caso contrário, prefixar ./é sempre uma boa idéia - imagine que você tenha criado um arquivo chamado -rfe depois chamado rm *.
Slhck 26/05
11
@slhck Para muitas pessoas que podem parecer uma piada. Mas já vi casos suficientes em que esse tipo de coisa destruiu (parte de) um servidor. Você não pode alertar as pessoas o suficiente sobre os perigos dos arquivos começando com um traço. Um local em que trabalhei ainda o tinha como regra oficial: nunca crie um arquivo cujo nome comece com "-f" ou "-r".
Tonny
11
Este deve ser a resposta: é a única maneira portátil ( --não é compreendido por todos os comandos, apenas alguns)
Olivier Dulac
@OlivierDulac Eu pensei que --era uma coisa bash, por isso deve funcionar para todos os programas?
gsingh2011
@ gsingh2011 não, o código que decide se "-" é considerado um marcador de "fim de sinalizadores" vive no aplicativo e cabe a cada aplicativo decidir se o trata dessa maneira.
Amos Shapira
4

A razão pela qual mkdir '-a', ou mkdir \-anão funciona, é porque esses dois métodos (usando aspas ou barras invertidas) são usados ​​para impedir que seu shell (provavelmente bash) lhes dê um significado especial. Como -anão significa nada de especial para o shell, isso não afeta a maneira como ele é repassado mkdir.

No que diz mkdirrespeito, ele recebe uma lista de argumentos do shell e não sabe se você os coloca entre aspas ou não, ou se houve uma barra invertida. Apenas vê um argumento -a. É por isso que você precisa do --explicado nas outras respostas.

hammar
fonte
-3

Além da resposta do "slhck", há outro truque que às vezes funciona:

Coloque o nome do arquivo em questão em 2 conjuntos de qoutes (diferentes) como "'-a'"ou '"-a"'.

Se isso funciona ou não depende do programa, mas é um último recurso se o programa não suportar o --recurso POSIX .
O método POSIX é sempre preferido, pois é 100% confiável.

Tonny
fonte
"O método POSIX é sempre preferido, pois é 100% confiável." Usar --para finalizar o processamento de opções também pressupõe que você não precisa de opções para seguir o nome do arquivo, o que nem sempre é o caso.
um CVn
@ MichaelKjörling Claro ... Mas eu meio que presumi que seria óbvio.
Tonny
4
Isto irá criar um arquivo chamado '-a'ou "-a", pelo menos em sistemas do tipo BSD
nohillside
4
Você pode citar um OS / shell onde isso faz trabalho?
Nohillside 26/05
11
se funcionasse, pareceria que você teria um problema bastante significativo ao lidar com arquivos com nomes entre aspas.
muhmuhten 27/05