Cosa significa "-" in "bash -"?


33

Cosa bash -significa nel seguente codice della shell bash? Sembra essere usato per prendere l'output dell'ultimo codice come input. In tal caso, posso semplicemente scriverlo come basho xargs bash?

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

Risposte:


36

In caso di dubbi, leggi il codice sorgente. =)

Bash 4.3, shell.clinea 830, in funzioneparse_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);

In altre parole, -sta dicendo che non ci sono più opzioni . Se ci fossero altre parole sulla riga di comando, verrebbero trattate come un nome file, anche se la parola inizia con a -.

Nel tuo esempio, ovviamente, questo -è completamente ridondante, poiché comunque non c'è nulla che lo segua. In altre parole, bash -è esattamente equivalente abash .


Bash prende i suoi comandi

  1. da un file di script, se fornito nella riga di comando, oppure
  2. in modo non interattivo dal suo stdin se il suo stdin non è un TTY (come nel tuo esempio: stdin è una pipe, quindi Bash eseguirà il contenuto di quell'URL come uno script), oppure
  3. interattivamente se il suo stdin è un TTY.

È un malinteso che bash -dice a Bash di leggere i suoi comandi dal suo input standard. Mentre è vero che nel tuo esempio, Bash leggerà i suoi comandi da stdin, lo avrebbe fatto indipendentemente dal fatto che ci fosse un -sulla riga di comando, perché, come detto sopra, bash -è identico a bash.

Per illustrare ulteriormente che -ciò non significa stdin, considerare:

  • Il catcomando è progettato per interpretare un -come stdin. Per esempio:

    $ 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
    
  • Al contrario, non puoi far eseguire Bash /bin/datequindi /bin/hostnameprovando questo:

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

    Piuttosto, cerca di interpretare /bin/hostnamecome un file di script di shell, che fallisce perché è un mucchio di gobbledygook binari.

  • Non è possibile eseguire date +%sutilizzando bash -neanche.

    $ 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
    

Puoi scrivere xargs bashinvece? No. curl | xargs bashinvocherebbe bash con il contenuto dello script come argomenti della riga di comando. La prima parola del contenuto sarebbe il primo argomento e probabilmente verrebbe interpretata erroneamente come un nome file di script.


6
voto per l'unica risposta giusta.
geirha,

Anzi: nelle parole della manpageAn argument of - is equivalent to --.
steeldriver,

Se xargsinvece volessi davvero usarlo , funzionerebbe (nello scenario limitato di uno script di input abbastanza piccolo) con | xargs bash -c; ma in realtà, questo non è un uso utile o idiomatico di xargs.
tripla il

@tripleee Se il contenuto dell'URL è qualcosa di più di un one-liner, allora le interruzioni di riga e altri delimitatori sarebbero probabilmente tutti sbagliati.
200_successo

Duh, hai ragione, ovviamente.
tripla il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.