Que signifie le "-" dans "bash -"?

33

Que bash -signifie dans le code shell bash suivant? Il semble être utilisé pour prendre en sortie le dernier code en entrée. Si oui, puis-je simplement l'écrire comme bashou xargs bash?

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

Réponses:

36

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

Bash 4.3, shell.cligne 830, en fonctionparse_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 d'autres termes, le -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 un -.

Dans votre exemple, bien entendu, cela -est complètement redondant, car rien n’y fait suite. En d'autres termes, bash -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 téléscripteur (comme dans votre exemple: stdin est un canal, Bash exécutera le contenu de cette URL sous forme de script), ou
  3. de manière interactive si son stdin est un ATS.

C'est une idée fausse qui bash -dit à Bash de lire ses commandes à partir de son entrée standard. S'il est vrai que, dans votre exemple, Bash lira ses commandes à partir de stdin, il l'aurait fait, qu'il y ait ou non une -ligne de commande, car, comme indiqué ci-dessus, bash -est identique à bash.

Pour illustrer davantage cela -ne signifie pas stdin, considérons:

  • La catcommande est conçue pour interpréter a en -tant que stdin. Par exemple:

    $ 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
  • En revanche, vous ne pouvez pas obtenir Bash pour exécuter /bin/dateensuite /bin/hostnameen essayant ceci:

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

    Au lieu de cela, il essaie d'interpréter /bin/hostnamecomme un fichier de script shell, ce qui échoue parce que c'est un tas de gobbledygook.

  • Vous ne pouvez pas exécuter en date +%sutilisant bash -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 à la xargs bashplace? No. curl | xargs bashinvoquerait bash avec le contenu du script comme arguments de ligne de commande. Le premier mot du contenu serait le premier argument, et il serait probablement interprété à tort comme un nom de fichier de script.

200_success
la source
6
upvote pour la seule bonne réponse.
geirha
En effet: pour reprendre les termes de la page de An argument of - is equivalent to --.
manuel
Si vous vouliez vraiment, vraiment utiliser xargs, cela fonctionnerait (dans le scénario limité d’un script d’entrée assez petit) avec | xargs bash -c; mais en réalité, ce n’est pas une utilisation utile ou idiomatique de xargs.
triple-
@tripleee Si le contenu de l'URL est autre chose qu'une ligne, les sauts de ligne et les autres délimiteurs seraient probablement tous erronés.
200_success
Duh, vous avez raison, bien sûr.
triple-