Apa Bash Shebang yang disukai?

1132

Apakah ada Bashshebang yang secara obyektif lebih baik daripada yang lain untuk sebagian besar kegunaan?

  • #!/usr/bin/env bash
  • #!/bin/bash
  • #!/bin/sh
  • #!/bin/sh -
  • dll

Saya samar-samar ingat beberapa waktu yang lalu mendengar bahwa menambahkan tanda hubung pada akhirnya mencegah seseorang mengirimkan perintah ke skrip Anda, tetapi tidak dapat menemukan detail tentang itu.

Kurtosis
sumber
4
Dan itu /usr/local/bin/bashdi OpenBSD.
jww

Jawaban:

1536

Anda harus menggunakan #!/usr/bin/env bashuntuk portabilitas : berbeda * nixes menempatkan bashdi tempat yang berbeda, dan menggunakan /usr/bin/envadalah solusi untuk menjalankan pertama bashditemukan pada PATH. Dan shtidakbash .

l0b0
sumber
9
Terima kasih. Juga terlihat seperti menambahkan - ke akhir $! / Usr / bin / env bash - tidak akan melakukan apa-apa karena hanya satu argumen yang diizinkan oleh * nix di shebang, dan itu digunakan oleh 'bash'. Itu tampaknya hanya berguna untuk mencegah argumen jahat diteruskan ke skrip pada commandline jika shebang skrip adalah salah satu dari yang lain tanpa argumen ( /bin/sh, dll).
Kurtosis
13
@ Ray bashtidak tinggal di /binsemua sistem.
ptierno
12
Bagi saya yang sama, saya hanya menambahkannya ke alias:, alias shebang='echo "#!/usr/bin/env bash"'sekarang saya hanya perlu membuka terminal dan mengetik shebang daripada pergi ke sini.
Oylex
19
Jawaban ini menipu. POSIX tidak mengatakan itu envdi /usr/bin/env. Bisa saja di /bin/envatau di mana saja pada kenyataannya, selama itu ada di jalan. Bisa jadi /dummy/envkalau /dummyada di PATH. Shebang sendiri tidak terdefinisi di bawah POSIX, jadi saya bisa #!stop toastermemulai mesin kopi USB dan menjadi POSIX. Jadi #!/usr/bin/env bashtidak terlalu baik daripada #!/bin/bashitu, bisa jadi lebih portabel tergantung.
darkfeline
19
@darkfeline Portabilitas tidak mutlak - secara matematis tidak mungkin membuat skrip apa pun yang akan melakukan hal yang sama pada setiap platform. Pada 2012 hingga 2018 /usr/bin/envada lebih banyak mesin daripada /bin/bashxor /usr/bin/bash, jadi skrip yang dimulai dengan baris ini akan melakukan hal yang diharapkan pada sebanyak mungkin mesin.
l0b0
80

/bin/shbiasanya merupakan tautan ke shell default sistem, yang sering bashtetapi aktif, misalnya, sistem Debian lebih ringan dash. Either way, shell Bourne asli adalah sh, jadi jika skrip Anda menggunakan beberapa bash(generasi ke-2, "Bourne Again sh") fitur tertentu ( [[ ]]tes, array, berbagai hal manis, dll.), Maka Anda harus lebih spesifik dan menggunakan nanti . Dengan cara ini, pada sistem di mana bash tidak diinstal, skrip Anda tidak akan berjalan. Saya mengerti mungkin ada trilogi film yang mengasyikkan tentang evolusi ini ... tapi itu bisa jadi kabar angin.

Juga perhatikan bahwa ketika dipicu sebagai sh, bashsampai batas tertentu berperilaku sebagai standar POSIX sh (lihat juga dokumentasi GNU tentang ini).

delicateLatticeworkFever
sumber
2
Public Domain Korn Shell (pdksh) adalah default pada OpenBSD.
jww
Sebagian besar sistem tidak akan terhubung /bin/shke mana pun /usrkarena hal itu akan membuat skrip init sulit dijalankan sebelum /usrdipasang.
aij
@aij Saya tidak tahu mengapa saya menempatkan "banyak atau sebagian besar" di sana - saya pengguna fedora, di mana /bindan /sbinselama bertahun-tahun baru saja symlink secara default, ke /usr/bindan /usr/sbin, jadi dalam konteks itu /bin/shadalah tautan ke bashdan yang sebenarnya direktori adalah /usr/bin. Tapi saya akan memperbaiki di atas.
delicateLatticeworkFever
44

Saya sarankan menggunakan:

#!/bin/bash

Ini bukan 100% portabel (beberapa sistem menempatkan bashdi lokasi selain /bin), tetapi kenyataan bahwa banyak skrip yang ada menggunakan #!/bin/bashtekanan berbagai sistem operasi untuk membuat /bin/bashsetidaknya symlink ke lokasi utama.

Alternatif dari:

#!/usr/bin/env bash

telah disarankan - tetapi tidak ada jaminan bahwa envperintah ada di /usr/bin(dan saya telah menggunakan sistem di mana tidak) Selain itu, formulir ini akan menggunakan contoh pertama bashdi pengguna saat ini $PATH, yang mungkin bukan versi yang sesuai dari bash shell.

(Tetapi /usr/bin/envharus bekerja pada sistem modern yang masuk akal, baik karena envdi dalam /usr/binatau karena sistem melakukan sesuatu untuk membuatnya bekerja. Sistem yang saya sebutkan di atas adalah SunOS 4, yang mungkin belum saya gunakan dalam sekitar 25 tahun.)

Jika Anda memerlukan skrip untuk dijalankan pada sistem yang tidak memiliki /bin/bashskrip, Anda dapat memodifikasi skrip untuk menunjuk ke lokasi yang benar (itu memang tidak nyaman).

Saya telah membahas pengorbanan secara lebih mendalam dalam jawaban saya untuk pertanyaan ini .

Pembaruan yang agak kabur: Satu sistem yang saya gunakan, Termux , lapisan desktop-Linux-like yang berjalan di bawah Android, tidak memiliki /bin/bash( bashtetapi /data/data/com.termux/files/usr/bin/bash) - tetapi ia memiliki penanganan khusus untuk didukung #!/bin/bash.

Keith Thompson
sumber
3
2-tahun kemudian dan ini masih merupakan saran terbaik di sini. Jika solusi sederhana tidak berhasil maka Anda harus mempertanyakan keputusan Anda sebelumnya. Jawaban yang diterima dan paling banyak dipilih tidak salah, itu hanya tidak benar :)
Software Engineer
27

Menggunakan garis shebang untuk memohon penerjemah yang tepat bukan hanya untuk BASH. Anda dapat menggunakan shebang untuk bahasa yang ditafsirkan pada sistem Anda seperti Perl, Python, PHP (CLI) dan banyak lainnya. Ngomong-ngomong, shebang

#!/bin/sh -

(bisa juga dua tanda hubung, yaitu --) mengakhiri opsi bash semuanya setelah akan diperlakukan sebagai nama file dan argumen.

Menggunakan envperintah membuat skrip Anda portabel dan memungkinkan Anda untuk mengatur lingkungan khusus untuk skrip Anda sehingga skrip portabel harus digunakan

#!/usr/bin/env bash

Atau untuk bahasa apa pun seperti untuk Perl

#!/usr/bin/env perl

Pastikan untuk melihat manhalaman untuk bash:

man bash

dan env:

man env

Catatan: Pada sistem berbasis Debian dan berbasis Debian, seperti Ubuntu, shditautkan ke dashtidak bash. Karena semua skrip sistem digunakan sh. Ini memungkinkan bash untuk tumbuh dan sistem tetap stabil, menurut Debian.

Juga, untuk menjaga doa * nix seperti saya tidak pernah menggunakan ekstensi file pada skrip yang dipanggil shebang, karena Anda tidak bisa menghilangkan ekstensi pada permintaan pada executable seperti yang Anda bisa pada Windows. Perintah file dapat mengidentifikasi itu sebagai skrip.

Jamie R Robillard Sr.
sumber
4

Ini benar-benar tergantung pada bagaimana Anda menulis skrip bash Anda. Jika Anda /bin/shterhubung ke bash, saat bash dipanggil sebagai sh, beberapa fitur tidak tersedia .

Jika Anda ingin fitur khusus bash, non-POSIX, gunakan #!/bin/bash

glenn jackman
sumber
3
Bash tidak diinstal pada OpenBSD. Jika Anda menginstal via pkg_add, maka terletak di /usr/local/bin, yang mungkin tidak di jalur.
jww
bagaimana dengan POSIXfitur?
Nikolan Asad