O que significa "-" em "bash -"?

33

O que bash -significa no seguinte código do shell bash? Parece ser usado para obter o último código de saída como entrada. Se sim, posso apenas escrever como bashou xargs bash?

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

Respostas:

36

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

Bash 4.3, shell.clinha 830, na funçãoparse_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);

Em outras palavras, -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 iniciasse com a -.

No seu exemplo, é claro, isso -é completamente redundante, pois não há nada a seguir. Em outras palavras, bash -é exatamente equivalente abash .


Bash assume seus comandos

  1. de um arquivo de script, se for fornecido na linha de comando, ou
  2. não interativamente a partir do stdin, se o stdin não for um TTY (como no seu exemplo: stdin é um canal, 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 -diz ao Bash para ler seus comandos a partir de sua entrada padrão. Embora seja verdade que, no seu exemplo, o Bash leia seus comandos a partir do stdin, ele o faria independentemente de haver um -na linha de comando, porque, como afirmado acima, bash -é idêntico a bash.

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

  • O catcomando foi projetado para interpretar a -como stdin. Por exemplo:

    $ 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
  • Em contraste, você não pode obter Bash para executar /bin/date, em seguida, /bin/hostnametentando este:

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

    Em vez disso, ele tenta interpretar /bin/hostnamecomo um arquivo de script de shell, que falha porque é um monte de bobagens bizarras.

  • Você também não pode executar date +%susando 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? No. curl | xargs bashinvocaria bash com o conteúdo do script como argumentos de linha de comando. A primeira palavra do conteúdo seria o primeiro argumento e provavelmente seria mal interpretado como um nome de arquivo de script.

200_success
fonte
6
voto positivo para a única resposta certa.
Geirha
Na verdade: nas palavras da página de manual #An argument of - is equivalent to --.
steeldriver
Se você realmente quisesse usá- xargslo, ele funcionaria (no cenário limitado de um script de entrada suficientemente pequeno) com | xargs bash -c; mas, na verdade, esse não é um uso útil ou idiomático xargs.
Tripleee
@tripleee Se o conteúdo da URL for algo além de uma linha, as quebras de linha e outros delimitadores provavelmente estarão todos errados.
200_success
Duh, você está certo, é claro.
Tripleee