Apa perbedaan antara #! / Bin / sh dan #! / Bin / bash?

281

jika saya menulis,

#!/bin/bash
echo "foo"

atau

#!/bin/sh
echo "foo"

keduanya menghasilkan sama. Saya telah melihat beberapa skrip dimulai dengan #!/bin/shatau #!/bin/bash. Apakah ada perbedaan di antara mereka?

Rahul Virpara
sumber

Jawaban:

242

bashdan shdua cangkang yang berbeda. Pada dasarnya bashadalah sh, dengan lebih banyak fitur dan sintaksis yang lebih baik. Kebanyakan perintah bekerja sama, tetapi berbeda.

Karena itu, Anda harus menyadari bahwa /bin/shsebagian besar sistem akan menjadi tautan simbolik dan tidak akan diminta sh. Di Ubuntu /bin/shdigunakan untuk menghubungkan bash, perilaku khas pada distribusi Linux, tetapi sekarang telah berubah untuk menautkan ke shell lain yang disebut dash . Saya akan menggunakan bash, karena itu cukup standar (atau paling tidak paling umum, dari pengalaman saya). Faktanya, masalah muncul ketika skrip bash akan digunakan #!/bin/shkarena pembuat skrip mengasumsikan tautannya adalah bashketika tidak perlu.

Untuk info lebih lanjut, http://man.cx/sh , http://man.cx/bash .

reverendj1
sumber
25
Paragraf pertama Anda cukup menyesatkan. "sh" sama sekali bukan shell, tetapi symlink ke shell sistem yang saat ini dikonfigurasi , yang pada sistem Linux biasanya berupa bash atau dash (versi terbaru Ubuntu menggunakan yang terakhir).
thomasrutter
19
/bin/shdulu shell yang disebut bourne shell kembali pada tahun 1977. bash adalah shell yang kompatibel dengan / bin / sh yang dapat digunakan sebagai pengganti shell bourne yang sesuai dengan posix. en.wikipedia.org/wiki/Bourne_shell
Alex
5
bash adalah standar de facto (sangat banyak digunakan) tetapi ini bukan "standar"; sh di Ubuntu menggunakan dash , yang merupakan shell yang kompatibel dengan Posix, jadi ini benar-benar standar. Saran saya adalah menggunakan tanda hubung sesering mungkin untuk skrip, terutama untuk skrip sisi server. Meskipun bash lebih ekspresif, dasbor berjalan lebih cepat dan lebih aman.
Rick-777
@ Rick-777 Jadi haruskah saya secara eksplisit menempatkan #! / Bin / dash di bagian atas skrip saya? Saya juga telah menulis skrip di mana saya hanya menulis perintah dan mengeksekusi dengan ./scriptName dan itu berfungsi dengan baik. Apakah #! / Bin / yourShellHere diperlukan?
user137717
@ Rick-777 Dalam kasus di mana saya mengecualikan #! / Bin / shellName, saya telah menamai file fileName.sh. Akankah itu secara implisit menghubungkan ke shell sistem yang disukai tanpa mendeklarasikan #! / Bin / sh?
user137717
82

Di Linux dan sistem mirip Unix lainnya, Anda memiliki beberapa pilihan shell.

Shell bertanggung jawab tidak hanya untuk menggambar prompt kecil Anda, tetapi menafsirkan perintah Anda, terutama jika Anda memasukkan logika yang rumit seperti pipa, kondisional dan sebagainya.

bash adalah shell yang paling umum digunakan sebagai shell default untuk pengguna sistem Linux. Ini adalah keturunan spiritual kerang lain yang digunakan sepanjang sejarah Unix. Namanya, bash adalah singkatan dari Bourne-Again Shell, sebuah penghormatan kepada shell Bourne yang dirancang untuk diganti, meskipun ia juga menggabungkan fitur-fitur dari C Shell dan Korn Shell.

Dijalankan, akhir-akhir ini, dari /bin/bash- sistem apa pun dengan bash akan membuatnya dapat diakses di sini.

Bukan hanya pengguna yang menggunakan kerang. Script ( skrip shell ) perlu shell untuk menafsirkannya. Saat Anda menjalankan skrip shell, sistem Anda harus memulai proses shell untuk menjalankan skrip Anda.

Masalahnya adalah, shell yang berbeda memiliki sedikit inkonsistensi kecil di antara mereka, dan ketika harus menjalankan skrip, ini bisa menjadi masalah nyata. bash memiliki cukup banyak fitur scripting yang unik hanya untuk bash, dan tidak untuk shell lainnya. Ini bagus, jika Anda akan selalu menggunakan bash untuk menjalankan skrip tersebut. Kerang lain mungkin mencoba untuk meniru bash, atau mematuhi standar POSIX, yang mendukung bash dengan cukup baik (meskipun menambahkan ekstensi sendiri ke).

Dimungkinkan untuk menentukan di bagian atas skrip shell yang shell itu harus dijalankan dengan menggunakan shebang. Sebuah skrip dapat menentukan #!/bin/bashpada baris pertama, artinya skrip harus selalu dijalankan dengan bash, bukan pada shell lain.

/ bin / sh adalah executable yang mewakili shell sistem . Sebenarnya, biasanya diimplementasikan sebagai tautan simbolik yang menunjuk ke executable untuk shell mana saja yang merupakan shell sistem. Shell sistem adalah jenis shell default yang harus digunakan skrip sistem. Dalam distribusi Linux, untuk waktu yang lama ini biasanya merupakan tautan simbolis ke bash , sedemikian rupa sehingga telah menjadi semacam konvensi untuk selalu menautkan / bin / sh ke bash atau shell yang kompatibel dengan bash. Namun, dalam beberapa tahun terakhir Debian (dan Ubuntu) memutuskan untuk mengganti sistem shell dari bash ke dash- shell serupa - melanggar tradisi lama di Linux (well, GNU) menggunakan bash untuk / bin / sh. Dash dipandang sebagai shell yang lebih ringan, dan jauh lebih cepat, yang dapat bermanfaat untuk kecepatan boot (dan hal-hal lain yang membutuhkan banyak skrip shell, seperti skrip instalasi paket).

Dash cukup kompatibel dengan bash, didasarkan pada standar POSIX yang sama. Namun, itu tidak menerapkan ekstensi khusus bash. Ada skrip yang menggunakan #!/bin/sh(sistem shell) sebagai shebang mereka, tetapi membutuhkan ekstensi bash-specific. Ini saat ini dianggap sebagai bug yang harus diperbaiki oleh Debian dan Ubuntu, yang membutuhkan / bin / sh untuk dapat bekerja ketika diarahkan ke dash.

Meskipun shell sistem Ubuntu mengarah ke dasbor, shell login Anda sebagai pengguna terus menjadi bash saat ini. Yaitu, ketika Anda masuk ke terminal emulator di mana saja di Linux, shell login Anda akan menjadi bash. Kecepatan operasi tidak begitu menjadi masalah ketika shell digunakan secara interaktif, dan pengguna terbiasa dengan bash (dan mungkin memiliki kustomisasi spesifik-bash di direktori home mereka).

Apa yang harus Anda gunakan saat menulis skrip

Jika skrip Anda hanya memerlukan fitur yang didukung oleh bash, gunakan #!/bin/bash.

Tetapi jika memungkinkan, akan lebih baik untuk memastikan skrip Anda kompatibel dengan POSIX, dan gunakan #!/bin/sh, yang harus selalu, cukup andal, arahkan ke shell sistem yang kompatibel dengan POSIX yang disukai dalam instalasi apa pun.

thomasrutter
sumber
18

Selain jawaban sebelumnya, meskipun /bin/shmerupakan tautan simbolis ke /bin/bash, #!/bin/shtidak sepenuhnya setara dengan #!/bin/bash.

Dari halaman manual bash (1) :

"Jika bash dipanggil dengan nama sh, ia mencoba untuk meniru perilaku startup versi historis sh sedekat mungkin, sambil menyesuaikan dengan standar POSIX juga."

Misalnya sintaks spesifik bash:

 exec  > >(tee logfile.txt)

memberikan kesalahan dalam shell yang diawali dengan #!/bin/sh, bahkan dengan tautan simbolis sh-> bash pada tempatnya.

AnkiF
sumber
6

GNU Bash: #!/bin/bash; POSIX shell: #!/bin/sh.

山 茶树 和 葡萄 树
sumber
Yah, jawaban singkat tapi akurat. 还 行
Sergiy Kolodyazhnyy