¿Cómo crear un archivo que se nombra como un argumento de línea de comando?

29

Me preguntaba cómo hacer un archivo con el nombre de una bandera, por ejemplo, si quisiera hacer una carpeta con nombre -a, ¿qué comandos funcionarían?

Probé mkdir '-a', mkdir \-ay tampoco funcionó. Estoy en Ubuntu

MI V
fuente
13
Las respuestas aquí son todos muy bien, pero no puedo pensar en una razón no trol a querer hacer esto ...
evilsoup
@evilsoup A algunas personas les gusta agregar prefijos a las carpetas para que queden en la parte superior de una lista ordenada alfanuméricamente. Pero esa es la única razón por la que puedo pensar, para ser honesto.
slhck
@slhck Sé de al menos un curso de edición de video en el que alientan a los estudiantes a agregar espacios en blanco a los directorios de sus proyectos para que aparezcan en la parte superior de los iMacs comunales. Esto fue feo y condujo a una escalada hilarante, pero al menos no sería potencialmente una ruptura del sistema ...
evilsoup
3
Principalmente esto es aquí por interés académico.
MYV
55
Cómic obligatorio: beesbuzz.biz/d/20110224.php
esponjoso

Respuestas:

49

Llame al comando así:

mkdir -- -a

Esto --significa que las opciones terminan después de eso, por lo que -ase interpreta literalmente y no como una opción mkdir. Encontrará esta sintaxis no solo en mkdir, sino en cualquier utilidad compatible con POSIX, excepto para echoy test. De la especificación :

El argumento - debe aceptarse como un delimitador que indica el final de las opciones. Los siguientes argumentos deben tratarse como operandos, incluso si comienzan con el carácter '-'. El argumento - no debe usarse como una opción o como un operando.

--Se recomienda usarlo como salvaguarda para casi cualquier acción en la que trate con nombres de archivos y desee asegurarse de que no rompan el comando, por ejemplo, cuando mueva archivos en un bucle, es posible que desee llamar a lo siguiente, de modo que un archivo llamado -iisn ' t (in?) correctamente analizado como una opción:

mv -- "$f" new-"$f"
slhck
fuente
La desventaja de este enfoque es precisamente que termina el procesamiento de opciones. Para un ejemplo simple de mkdir, eso hace maravillas; si realmente necesita una opción para seguir el nombre del archivo en la línea de comando, no funcionará en absoluto.
un CVn
1
Por supuesto, hay un inconveniente en todo. En los casos en que trata con nombres de archivos intercalados con opciones, la solución de Amos sería la única alternativa sensata que se me ocurre, pero realmente depende de cómo la herramienta analiza las opciones.
slhck
1
Dado que el OP habla de crear un archivo con un nombre "como un argumento de línea de comando" (supongamos que significa un nombre que comienza con un guión), no creo que sea una suposición completamente irracional. Tómelo cc -o -myfile -Wall -myfile.ccomo un ejemplo ligeramente artificial. Cualquier editor que valga la pena debería poder guardarlo en un archivo llamado -myfile.csi se lo solicita, pero el compilador de C probablemente no hará lo que quiere cuando se le dé dicha lista de opciones.
un CVn
1
@Maksim Por ejemplo, los comandos que requieren una opción para establecer un nombre de archivo de entrada o salida, como el cccomando que Michael dio anteriormente, que tiene la -oopción de especificar el archivo de salida.
slhck
1
El ejemplo del bucle es por qué siempre debes usar algo como en for f in ./*; do...lugar defor f in *; do...
evilsoup
21

La forma más sencilla que debería funcionar con cualquier programa razonable es usar un nombre de ruta relativo delante de -, por ejemplo mkdir ./-a, creará un directorio llamado -aen el directorio de trabajo actual.

El ejemplo más común de uso de este "truco" es cuando desea eliminar un archivo que comienza con un guión, para que pueda hacerlo rm ./-a.

Amos Shapira
fuente
3
Por supuesto, eso solo funciona si está trabajando con rutas de archivos y no con opciones de línea de comandos arbitrarias que se analizan como cadenas. Pero de lo contrario, los prefijos ./siempre son una buena idea: imagine que creó un archivo llamado -rfy luego llamó rm *.
slhck
1
@slhck Para muchas personas que podrían parecer una broma. Pero he visto suficientes casos en los que este tipo de cosas aniquiló (parte de) un servidor. No se puede advertir a la gente lo suficiente sobre los peligros de los archivos que comienzan con un guión. Un lugar en el que trabajé incluso lo tenía como regla oficial: nunca crees un archivo cuyo nombre comience con "-f" o "-r".
Tonny
1
Esta debería ser la respuesta: es la única forma portátil ( --no se entiende por todos los comandos, solo algunos)
Olivier Dulac
@OlivierDulac Pensé que --era una cosa bash, ¿así que debería funcionar para todos los programas?
gsingh2011
@ gsingh2011 no, el código que decide si "-" se considera como un marcador de "fin de banderas" vive en la aplicación y depende de cada aplicación decidir si lo trata de esa manera.
Amos Shapira
4

La razón por la cual mkdir '-a', o mkdir \-ano funciona es porque ambos métodos (usando comillas o barras invertidas) se utilizan para evitar que su shell (probablemente bash) les dé un significado especial. Como de -atodos modos no significa nada especial para el shell, estos no tienen ningún efecto sobre cómo se transmite mkdir.

En lo que a él mkdirrespecta, recibe una lista de argumentos del shell, y no puede decir si los puso entre comillas o no, o si hubo una barra invertida. Solo ve un argumento -a. Es por eso que necesita lo --que se explica en las otras respuestas.

hammar
fuente
-3

Además de la respuesta de "slhck" hay otro truco que a veces funciona:

Ponga el nombre de archivo en cuestión dentro de 2 conjuntos de qoutes (diferentes) como "'-a'"o '"-a"'.

Si esto funciona o no depende del programa, pero es un último recurso si el programa no admite la --función POSIX .
Siempre se prefiere el método POSIX ya que es 100% confiable.

Tonny
fuente
"Siempre se prefiere el método POSIX, ya que es 100% confiable". El uso --para finalizar el procesamiento de opciones también supone que no necesita ninguna opción para seguir el nombre del archivo, que no siempre es el caso.
un CVn
@ MichaelKjörling Por supuesto ... Pero supuse que sería obvio.
Tonny
44
Esto creará un archivo llamado '-a'o "-a", al menos en sistemas de tipo BSD
nohillside
44
Se puede citar un OS / shell en el que este hace el trabajo?
nohillside
1
si funcionara, parecería que tendría un problema bastante significativo al tratar con archivos con nombres entre comillas.
Muhmuhten