¿Qué significa "-" en "bash -"?

33

¿Qué bash -significa en el siguiente código de shell bash? Parece que se usa para tomar la salida del último código como entrada. Si es así, ¿puedo escribirlo como basho xargs bash?

curl --silent --location https://rpm.nodesource.com/setup | bash -
Searene
fuente

Respuestas:

36

En caso de duda, lea el código fuente. =)

Bash 4.3, shell.clínea 830, en funciónparse_shell_options() :

  /* A single `-' signals the end of options.  From the 4.3 BSD sh.
     An option `--' means the same thing; this is the standard
     getopt(3) meaning. */
  if (arg_string[0] == '-' &&
       (arg_string[1] == '\0' ||
         (arg_string[1] == '-' && arg_string[2] == '\0')))
    return (next_arg);

En otras palabras, -está diciendo que no hay más opciones . Si hubiera más palabras en la línea de comando, se tratarían como un nombre de archivo, incluso si la palabra comenzara con a -.

En su ejemplo, por supuesto, eso -es completamente redundante, ya que no hay nada que lo siga de todos modos. En otras palabras, bash -es exactamente equivalente abash .


Bash toma sus comandos

  1. desde un archivo de script si se proporciona en la línea de comando, o
  2. no interactivamente desde su stdin si su stdin no es un TTY (como en su ejemplo: stdin es una tubería, por lo que Bash ejecutará el contenido de esa URL como un script), o
  3. interactivamente si su stdin es un TTY.

Es un concepto erróneo que bash -le dice a Bash que lea sus comandos desde su entrada estándar. Si bien es cierto que en su ejemplo, Bash leerá sus comandos de stdin, lo habría hecho independientemente de si había un -en la línea de comando, porque, como se indicó anteriormente, bash -es idéntico a bash.

Para ilustrar más a fondo que -no significa stdin, considere:

  • El catcomando está diseñado para interpretar a -como stdin. Por ejemplo:

    $ echo xxx | cat /etc/hosts - /etc/shells
    127.0.0.1 localhost
    xxx
    # /etc/shells: valid login shells
    /bin/sh
    /bin/dash
    /bin/bash
    /bin/rbash
    /bin/zsh
    /usr/bin/zsh
    /usr/bin/screen
    /bin/tcsh
    /usr/bin/tcsh
    /usr/bin/tmux
    /bin/ksh93
    
  • Por el contrario, no se puede conseguir Bash para ejecutar /bin/datea continuación, /bin/hostnameal tratar lo siguiente:

    $ echo date | bash - hostname
    /bin/hostname: /bin/hostname: cannot execute binary file
    

    Más bien, trata de interpretarlo /bin/hostnamecomo un archivo de script de shell, que falla porque es un montón de gobbledygook binario.

  • No se puede ejecutar date +%susando bash -tampoco.

    $ date +%s
    1448696965
    $ echo date | bash -
    Sat Nov 28 07:49:31 UTC 2015
    $ echo date | bash - +%s
    bash: +%s: No such file or directory
    

¿Puedes escribir en su xargs bashlugar? No. curl | xargs bashinvocaría a bash con el contenido del script como argumentos de línea de comandos. La primera palabra del contenido sería el primer argumento, y probablemente se malinterpretaría como un nombre de archivo de script.

200_success
fuente
66
Vota por la única respuesta correcta.
geirha
De hecho: en palabras de la página de An argument of - is equivalent to --.
manual
Si realmente quisiera usarlo xargs, funcionaría (en el escenario limitado de un script de entrada lo suficientemente pequeño) con | xargs bash -c; pero realmente, este no es un uso útil o idiomático de xargs.
tripleee
@tripleee Si el contenido de la URL es algo más que una línea, entonces los saltos de línea y otros delimitadores probablemente estarían equivocados.
200_success
Duh, tienes razón, por supuesto.
tripleee