Que signifie le «-» dans «bash -»?

30

Que signifie bash - dans le code de shell bash suivant? Il semble être utilisé pour prendre en sortie le dernier code en tant qu'entrée. Si oui, puis-je simplement l'écrire sous la forme bash ou xargs bash ?

curl --silent --location https://rpm.nodesource.com/setup | bash -
    
posée Searene 28.11.2015 - 03:28
la source

1 réponse

34

En cas de doute, lisez le code source. =)

shell.c :

  /* 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] == '
$ 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
' || (arg_string[1] == '-' && arg_string[2] == '
$ echo date | bash - hostname
/bin/hostname: /bin/hostname: cannot execute binary file
'))) return (next_arg);

En d'autres termes, le parse_shell_options() dit qu'il n'y a plus d'options . S'il y avait plus de mots sur la ligne de commande, ils seraient traités comme un nom de fichier, même si le mot commençait par - .

Dans votre exemple, bien sûr, - est complètement redondant, car rien n’y fait suite. En d'autres termes, - est exactement équivalent à bash - .

Bash prend ses commandes

  1. à partir d'un fichier de script s'il est fourni sur la ligne de commande, ou
  2. de manière non interactive à partir de son stdin si son stdin n'est pas un TTY (comme dans votre exemple: stdin est un canal, Bash exécutera le contenu de cette URL en tant que script) ou
  3. interactivement si son stdin est un TTY.

Il est faux de croire que bash dit à Bash de lire ses commandes à partir de son entrée standard. Bien qu'il soit vrai que dans votre exemple, Bash lira ses commandes à partir de stdin, il l'aurait fait qu'il y ait ou non bash - sur la ligne de commande car, comme indiqué ci-dessus,- est identique à bash - .

Pour illustrer davantage que bash ne signifie pas stdin, considérons:

  • La commande - est conçue pour interpréter un cat en tant que stdin. Par exemple:

    $ 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
    
  • En revanche, vous ne pouvez pas obliger Bash à exécuter - puis /bin/date en essayant ceci:

      /* 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] == '
    $ 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
    
    ' || (arg_string[1] == '-' && arg_string[2] == '
    $ echo date | bash - hostname
    /bin/hostname: /bin/hostname: cannot execute binary file
    
    '))) return (next_arg);

    Il tente plutôt d'interpréter /bin/hostname en tant que fichier de script shell, ce qui échoue car il s'agit d'un tas de gobbledygook.

  • Vous ne pouvez pas exécuter /bin/hostname en utilisant date +%s non plus.

    $ 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
    

Pouvez-vous écrire bash - à la place? Non, xargs bash invoquerait bash avec le contenu du script sous forme d'arguments de ligne de commande. Le premier mot du contenu serait le premier argument, et il serait probablement mal interprété comme un nom de fichier de script.

    
réponse donnée 200_success 28.11.2015 - 08:22
la source

Lire d'autres questions sur les étiquettes