Bash Shebang untuk boneka?

36

Saya punya beberapa skrip bash yang saya set up yang kebanyakan digunakan

#!/bin/bash

tapi saya secara teratur menemukan beberapa yang terlihat seperti

#!/bin/bash -e
#!/bin/bash -x
#!/bin/bash -ex

dan seterusnya.

Bisakah seseorang menjelaskan arti dan manfaat dari opsi shebang ini dan apakah itu berlaku untuk shebang lain?

Coneybeare
sumber
Opsi-opsi itu khusus untuk Bash (atau penerjemah lain). Mereka mungkin sama untuk shell lain (dash dan ksh, misalnya), tetapi mereka akan berbeda untuk penerjemah lain seperti AWK dan Python. Anda dapat menggunakan banyak opsi yang diterima juru bahasa. Opsi-opsi tersebut adalah khusus juru bahasa sementara shebang adalah fitur kernel.
Dijeda sampai pemberitahuan lebih lanjut.

Jawaban:

41

Jika skrip /path/to/foodimulai dengan #!/bin/bash, maka mengeksekusi /path/to/foo arg1 arg2sama dengan mengeksekusi /bin/bash /path/too/foo arg1 arg2. Jika garis shebang adalah #!/bin/bash -ex, itu setara dengan mengeksekusi /bin/bash -ex /path/too/foo arg1 arg2. Fitur ini dikelola oleh kernel.

Perhatikan bahwa Anda hanya dapat memiliki satu argumen pada baris shebang: beberapa unit (seperti Linux) hanya menerima satu argumen, sehingga #!/bin/bash -e -xakan menyebabkan bash menerima argumen lima karakter tunggal -e -x(kesalahan sintaks) daripada dua argumen -edan -x.

Untuk cangkang Bourne shdan cangkang turunan seperti POSIX sh, bash, ksh, dan zsh:

  • -e berarti bahwa jika ada perintah gagal (yang ditunjukkan dengan mengembalikan status bukan nol), skrip akan segera berakhir.
  • -x menyebabkan shell untuk mencetak jejak eksekusi.

Program lain mungkin memahami opsi ini tetapi dengan makna berbeda.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
24

Mereka adalah opsi yang dilewatkan untuk bashmelihat help setinfo lebih lanjut, dalam hal ini:

-x  Print commands and their arguments as they are executed.
-e  Exit immediately if a command exits with a non-zero status.
cYrus
sumber
3
+1 Dan -exmelakukan keduanya
Nifle
Ini membingungkan karena mereka terlihat seperti opsi baris perintah yang diteruskan ke Bash.
Caoilte
2
@Caoilte: Dan memang mereka (dari man bash): In addition to the single-character shell options documented in the description of the set builtin command, bash interprets the following options when it is invoked: [...].
cYrus
1
arrgh! berkedip dan Anda melewatkannya! :)
Caoilte
0

Saya hanya ingin menyebutkan alternatif yang lebih baik - seperti pada yang lebih portabel -:

#!/usr/bin/env bash

Contoh di atas digunakan envuntuk menemukan bashexecutable, yang tidak selalu di /bin/bash. Ye Olde #!/bin/bashscript tidak bekerja pada NixOS , misalnya.

Jika Anda menggunakan envseperti yang ditunjukkan di atas, Anda tidak dapat menyediakan argumen seperti -euntuk bash(sejauh yang saya tahu). Tetapi Anda dapat melakukan ini sebagai gantinya:

#!/usr/bin/env bash
set -e
Simon Alling
sumber
2
Saya melakukan ini sepanjang waktu, tetapi saya tidak akan mengatakan itu "lebih portabel" - pada kenyataannya, risiko memiliki pengguna menjalankan sesuatu yang sama sekali berbeda (dari apa yang Anda anggap sebagai sistem pengiriman kapal) jauh lebih besar. Sebagai contoh, Ubuntu masih mengirimkan Bash 4, sementara pengguna dapat memilih untuk menjalankan Bash 5.
slhck
Ya envpenggunaannya tidak baik terutama untuk skrip yang menjalankan python karena Anda tidak tahu apakah defaultnya pythonadalah versi 2 atau 3 dan itu membuat perbedaan dunia untuk skrip yang membutuhkan versi tertentu. Lebih baik untuk menjadi eksplisit daripada licik
smac89