¿Qué significa el último "-" (guión) en las opciones de `bash`?

15

En este tutorial necesitamos ejecutar el siguiente comando:

# curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

¿Qué significa el último -(guión) después bash?

He visto muchos comandos con esto, y no pude encontrar una explicación lógica y tampoco encontrar la forma de reformular una búsqueda en Google. ¿Es la salida del comando canalizado?

Omar BISTAMI
fuente
55
La misma pregunta en Ask Ubuntu , ¡con el mismo ejemplo!
200_success
2
Descargar cosas de la red y conectarlas directamente a sudo bashsonidos realmente aterrador. Intente buscar un tutorial que no fomente tales prácticas.
hmakholm dejó a Mónica el
Es el tutorial de npm, pero estoy de acuerdo contigo ...
Omar BISTAMI
1
Si necesita buscar cosas con símbolos, intente symbolhound.com.
Joe

Respuestas:

31

Bash se comporta de una manera algo no estándar cuando se trata de -.

POSIX dice:

Pauta 10:
El primer --argumento que no es un argumento de opción 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.

[...]

Directriz 13:
Para las utilidades que usan operandos para representar archivos que se abrirán para lectura o escritura, el -operando debe usarse para significar solo entrada estándar (o salida estándar cuando está claro desde el contexto que se está especificando un archivo de salida) o un archivo llamado -.

Y

Cuando una utilidad descrita en el volumen de Shell y Utilidades de POSIX.1-2017 como conforme a estas pautas se requiere para aceptar, o no aceptar, el operando -para significar entrada o salida estándar, este uso se explica en la sección OPERANDS. De lo contrario, si dicha utilidad utiliza operandos para representar archivos, se define la implementación si el operando -significa entrada estándar (o salida estándar) o un archivo llamado -.

Pero luego man 1 bashlee:

A --señala el final de las opciones y desactiva el procesamiento adicional de opciones. Cualquier argumento después de la --se trata como nombres de archivo y argumentos. Un argumento de -es equivalente a --.

Entonces, para Bash -no significa entrada estándar ni un archivo, por lo tanto, algo no estándar.

Ahora tu caso particular:

curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

Yo sospecho que el autor de este comando no se dan cuenta -es equivalente a --en este caso. Yo sospecho que el autor quería asegurarse de que bashva a leer desde la entrada estándar, que esperaban -al trabajo de acuerdo con la directriz 13.

Pero incluso si funcionara de acuerdo con la directriz, -sería innecesario aquí porque bashdetecta cuándo su entrada estándar es una tubería y actúa en consecuencia (a menos que -cse indique, etc.).

Sin embargo -, no funciona de acuerdo con la directriz, funciona como --. Todavía --es innecesario aquí porque no hay argumentos después.

En mi opinión, el último -no cambia nada. El comando funcionaría sin él.

Para ver cómo --y -puede ser útil en general, estudie el siguiente ejemplo.


caten mi Kubuntu obedece ambas pautas y lo usaré para demostrar la utilidad de -y --.

Deje que fooexista un archivo llamado . Esto imprimirá el archivo:

cat foo

Deje que --helpexista un archivo llamado . Esto no imprimirá el archivo:

cat --help

Pero esto imprimirá el archivo llamado --help:

cat -- --help

Esto concatenará el archivo nombrado --helpcon lo que provenga de la entrada estándar:

cat -- --help -

Parece que realmente no lo necesita --, porque siempre puede pasar lo ./--helpque seguramente se interpretará como un archivo. Pero considera

cat "$file"

cuando no sabes de antemano cuál es el contenido de la variable. No puede simplemente anteponerse ./a él, porque puede ser un camino absoluto y ./lo rompería. Por otro lado, puede ser un archivo llamado --help(porque ¿por qué no?). En este caso --es muy útil; Este es un comando mucho más robusto:

cat -- "$file"
Kamil Maciorowski
fuente
6

En man bash, al final de las opciones de un solo carácter hay: -

--    A -- signals the end of options and disables further option processing.
      Any arguments after the -- are treated as filenames and arguments. An
      argument of - is equivalent to --.

Si ha citado el comando completo, no veo ninguna razón para el uso -después bashen este caso, pero no hace ningún daño.

AFH
fuente
Gracias por su respuesta, sí, he citado el comando completo. así que cualquier cosa después de - o - no se verá como una opción sino como un nombre de archivo o argumentos, ¿podría dar un ejemplo donde sea útil?
Omar BISTAMI
1
Realmente es para permitir un script cuyo nombre comienza -, un requisito poco probable, pero -/ lo --hace posible.
AFH
1
@OmarBISTAMI Citar un comando afectará la forma en que el shell lo expande, pero no afectará ninguno de los argumentos que lo siguen. Si extiende las citas alrededor de argumentos legítimos, se convierten en parte del nombre del comando que tampoco es lo que desea. Hay algunos comandos que toman nombres de archivos como argumentos, pero no usan la entrada estándar de forma predeterminada. Un ejemplo artificial le permite intercalar la entrada (desde un terminal o una tubería) entre dos archivos. cat file1 - file2 > file3.
Joe
1
curl -sL https://rpm.nodesource.com/setup_6.x | sudo -E bash -

bash -significa que bashestá esperando stdin. Así que prácticamente bash ejecutará lo que sea devuelto por el comando que está a la izquierda de|

Un ejemplo similar pero más fácil sería:

echo hello | cat - aquí, catimprimirá 'hola'. ¿Por qué? Porque 'hola' se está enviando al gato |y catestá esperando que se le envíe algo

Ahora separemos todo el comando en dos:

curl -sL https://rpm.nodesource.com/setup_6.x

este comando curl devolverá algo que bash puede entender y ejecutar

entonces tenemos una tubería |que enviará la salida devuelta por el comando curl al lado derecho de la tubería, es decir sudo -E bash -. Finalmente sudo -E bash -, bash está listo para ejecutar cualquier cosa que se le envíe

Haris Muzaffar
fuente