39 votes

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

Qu'est-ce que bash - dans le code bash suivant Shell ? Il semble être utilisé pour prendre la sortie du dernier code comme entrée. Si c'est le cas, puis-je simplement l'écrire comme bash o xargs bash ?

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

41voto

200_success Points 997

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

Le tableau de bord 4.3, shell.c ligne 830, dans la fonction parse_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 - est de dire qu'il y a des plus d'options . S'il y a d'autres mots sur la ligne de commande, ils seront traités comme un nom de fichier, même si le mot commence par un - .

Dans votre exemple, il s'agit bien sûr - est complètement redondant, car il n'y a rien qui le suit de toute façon. En d'autres termes, bash - est exactement équivalent à bash .


Bash prend ses commandes

  1. à partir d'un fichier 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 pipe, donc Bash exécutera le contenu de cette URL en tant que script), ou
  3. de manière interactive si son stdin est un TTY.

Il est faux de croire que bash - indique à Bash de lire ses commandes à partir de l'entrée standard. Pendant qu'il est Il est vrai que dans votre exemple, Bash lira ses commandes à partir de stdin, mais il l'aurait fait indépendamment de l'existence ou non d'un fichier - sur la ligne de commande, car, comme indiqué ci-dessus, bash - est identique à bash .

Pour mieux illustrer cela - ne signifie pas stdin :

  • En cat La commande est conçue pour interpréter un - comme 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, il n'est pas possible d'obtenir de Bash qu'il exécute /bin/date puis /bin/hostname en essayant ceci :

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

    Elle tente plutôt d'interpréter /bin/hostname comme un fichier Shell Shell, ce qui échoue parce que c'est un tas de charabia binaire.

  • Vous ne pouvez pas exécuter date +%s en utilisant bash - soit.

    $ 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 xargs bash à la place ? Non. curl | xargs bash invoquerait 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é comme un nom de fichier script.

0voto

JohnSmith Points 1217

L'objectif de cette commande est de diriger la sortie de la commande curl vers bash afin qu'il exécute immédiatement les commandes renvoyées par curl. En fait, elle demande à bash d'obtenir ses données d'entrée à partir de stdin. Voir https://superuser.com/a/1494190/234355

Toutefois, dans cette même réponse, la question de savoir si cela fonctionne réellement ou non fait l'objet d'une discussion. Si vous exécutez simplement la première partie de la commande dans la question curl --silent --location https://rpm.nodesource.com/setup il produira un script bash valide. Je n'ai pas essayé, ne voulant pas exécuter un script inconnu provenant d'internet.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X