O que significa “-” em “bash -”?

30

O que significa bash - no seguinte código de shell bash? Parece ser usado para tirar a saída do último código como entrada. Em caso afirmativo, posso apenas escrevê-lo como bash ou xargs bash ?

curl --silent --location https://rpm.nodesource.com/setup | bash -
    
por Searene 28.11.2015 / 03:28

1 resposta

34

Em caso de dúvida, leia o código-fonte. =)

Bash 4.3, shell.c linha 830, em função 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] == '
$ 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);

Em outras palavras, o - está dizendo que não há mais opções . Se houvesse mais palavras na linha de comando, elas seriam tratadas como um nome de arquivo, mesmo que a palavra tenha começado com - .

No seu exemplo, é claro, que - é completamente redundante, já que não há nada seguindo isso de qualquer maneira. Em outras palavras, bash - é exatamente equivalente a bash .

Bash leva seus comandos

  1. de um arquivo de script, se fornecido na linha de comando, ou
  2. não interativamente de seu stdin se seu stdin não for um TTY (como no seu exemplo: stdin é um canal, então o Bash executará o conteúdo desse URL como um script) ou
  3. interativamente se seu stdin for um TTY.

É um equívoco que bash - diga ao Bash para ler seus comandos a partir de sua entrada padrão. Embora seja verdade que no seu exemplo, o Bash lerá seus comandos do stdin, isso teria acontecido independentemente de haver - na linha de comando, porque, como declarado acima, bash - é idêntico a bash .

Para ilustrar melhor que - não significa stdin, considere:

  • O comando cat foi projetado para interpretar um - como stdin. Por exemplo:

    $ 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
    
  • Por outro lado, você não pode fazer com que o Bash execute /bin/date e /bin/hostname tentando isso:

      /* 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);

    Em vez disso, ele tenta interpretar /bin/hostname como um arquivo de script shell, que falha porque é um monte de gobbledygook binário.

  • Você não pode executar date +%s usando bash - .

    $ 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
    

Você pode escrever xargs bash ? Não. curl | xargs bash invocaria o bash com o conteúdo do script como argumentos da linha de comando. A primeira palavra do conteúdo seria o primeiro argumento e provavelmente seria mal interpretada como um nome de arquivo de script.

    
por 200_success 28.11.2015 / 08:22