Apa arti "-" dalam "bash -"?

33

Apa bash -artinya dalam kode shell bash berikut? Tampaknya digunakan untuk mengambil output kode terakhir sebagai input. Jika demikian, dapatkah saya menuliskannya sebagai bashatau xargs bash?

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

Jawaban:

36

Jika ragu, baca kode sumber. =)

Bash 4.3, shell.cbaris 830, dalam fungsiparse_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);

Dengan kata lain, -ini mengatakan bahwa tidak ada opsi lagi . Jika ada kata lagi di baris perintah, mereka akan diperlakukan sebagai nama file, bahkan jika kata itu dimulai dengan a -.

Dalam contoh Anda, tentu saja, itu -sepenuhnya berlebihan, karena tidak ada yang mengikutinya juga. Dengan kata lain, bash -persis sama denganbash .


Bash mengambil perintahnya

  1. dari file skrip jika disediakan di baris perintah, atau
  2. non-interaktif dari stdinnya jika stdinnya bukan TTY (seperti dalam contoh Anda: stdin adalah sebuah pipa, jadi Bash akan mengeksekusi isi URL itu sebagai skrip), atau
  3. secara interaktif jika stdinnya adalah TTY.

Ini adalah kesalahpahaman yang bash -memberitahu Bash untuk membaca perintahnya dari input standarnya. Sementara itu adalah benar bahwa dalam contoh Anda, Bash akan membaca perintah nya dari stdin, itu akan melakukannya terlepas dari apakah ada -pada baris perintah, karena, sebagaimana dinyatakan di atas, bash -identik dengan bash.

Untuk menggambarkan lebih jauh itu -tidak berarti stdin, pertimbangkan:

  • The catperintah dirancang untuk menafsirkan -sebagai stdin. Sebagai contoh:

    $ 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
    
  • Sebaliknya, Anda tidak bisa mendapatkan Bash untuk dieksekusi /bin/datekemudian /bin/hostnamedengan mencoba ini:

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

    Sebaliknya, ia mencoba untuk menafsirkan /bin/hostnamesebagai file skrip shell, yang gagal karena itu adalah kumpulan buku biner biner.

  • Anda tidak dapat mengeksekusi date +%smenggunakan bash -keduanya.

    $ 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
    

Bisakah Anda menulis xargs bashsaja? Tidak. curl | xargs bashAkan memanggil bash dengan isi skrip sebagai argumen baris perintah. Kata pertama dari konten akan menjadi argumen pertama, dan kemungkinan akan disalahartikan sebagai nama file skrip.

200_sukses
sumber
6
pilih satu-satunya jawaban yang benar.
geirha
Memang: dalam kata-kata manpageAn argument of - is equivalent to --.
steeldriver
Jika Anda benar-benar ingin menggunakannya xargs, itu akan berfungsi (dalam skenario terbatas dari skrip input yang cukup kecil) dengan | xargs bash -c; tapi sungguh, ini bukan penggunaan yang berguna atau idiomatik xargs.
tripleee
@ tripleee Jika isi URL lebih dari satu baris, maka baris terputus dan pembatas lainnya mungkin semuanya salah.
200_sukses
Duh, kamu benar, tentu saja.
tripleee