Apakah ada alasan untuk meminta shebang menunjuk pada / bin / sh daripada / bin / bash?

53

Di sebagian besar skrip shell yang saya lihat (selain yang belum saya tulis sendiri), saya perhatikan bahwa shebang diatur ke #!/bin/sh. Ini tidak benar-benar mengejutkan saya pada skrip yang lebih lama, tetapi skrip yang ada juga cukup baru.

Apakah ada alasan untuk memilih /bin/shlebih /bin/bash, karena bashcukup banyak di mana-mana, dan sering default, pada banyak mesin Linux dan BSD kembali lebih dari satu dekade?

Jules
sumber
23
Ini adalah partice yang baik untuk digunakan /bin/shjika Anda tidak menggunakan bashfungsi tertentu . Suatu hari Anda bisa menggunakan salah satu skrip Anda pada sistem yang tidak diinstal (server jarak jauh, komputer yang disematkan ...)
Mathieu
1
secara umum Anda harus menghindari mengajukan pertanyaan yang cocok dengan jawaban berdasarkan pendapat (yang merupakan satu-satunya cara saya percaya pertanyaan ini dapat dijawab - tapi itu hanya pendapat saya ) .
mikeserv
9
Saya percaya bahwa adalah mungkin untuk menjawab pertanyaan ini tanpa melibatkan pendapat belaka, dengan menunjuk setidaknya dua organisasi yang menangani hal ini selama beberapa tahun, dan melihat sejarah dan hasilnya. Dengan banyak bacaan lebih lanjut terlampir, untuk boot. ☺
JdeBP
3
@JulesMazur ...the answers so far are fairly subjective...Pernyataan "subyektif" pada dasarnya didasarkan pada definisi. /bin/bashseharusnya hanya digunakan ketika bash secara eksplisit diperlukan. Dalam 40+ tahun sebagai pengembang, jauh sebelumnya bash, saya hampir tidak pernah secara eksplisit membutuhkannya kecuali saat pengujian. (Saya juga berusaha untuk menghindari ekstensi shell, tetapi sebagian besar skrip saya ditujukan untuk distribusi.) Banyak skrip di internet juga harus ditujukan untuk penggunaan luas.
user2338816
2
@ user2338816 salahku, maksudku objektif . Terima kasih atas poin Anda!
Jules

Jawaban:

83
  1. Ada beberapa sistem yang tidak mengirim bash secara default (mis. FreeBSD).
  2. Bahkan jika bash diinstal, itu mungkin tidak terletak di /bin.
  3. Kebanyakan skrip sederhana tidak memerlukan bash.
  4. Menggunakan shell POSIX lebih portabel dan skrip akan berjalan pada berbagai sistem yang lebih besar.
Marco
sumber
17
Alasan lain: sering / bin / sh lebih cepat dari bash, atau setidaknya memuat lebih cepat (karena lebih kecil).
derobert
5
@derobert, /bin/shlebih cepat jika tidak bash, masih ada beberapa sistem seperti OS / X atau RHEL mana /bin/shadalah bash.
Stéphane Chazelas
1
Tidak. Beberapa OS menghubungkannya, karena bash kompatibel ke belakang.
Sobrique
7
Cukup beberapa script menganggap bahwa /bin/shadalah /bin/bash. Perpindahan Ubuntu dari bash ke dash merusak semuanya.
atamanroman
19
@atamanroman: Skripnya salah sejak awal, mereka seharusnya digunakan #!/bin/bashjika mereka menginginkan Bash (tidak ada yang salah dengan itu!). Perubahan itu sebagian besar dilakukan di hulu di Debian. Itu meningkatkan pengalaman pengguna, itu memiliki dampak yang terukur pada waktu startup sistem. Ini juga berdampak positif terhadap keamanan, lihat "Shellshock".
Dietrich Epp
28

Sebagian besar skrip sistem dalam (terkait Debian: Ubuntu, Mint, dll.) Linux ditulis untuk berjalan di dasbor lebih cepat, yang merupakan default / bin / sh dalam sistem tersebut. Alasannya ada dua:

  • Kecepatan sistem. Kode dasbor yang lebih kecil memuat lebih cepat dan juga berjalan lebih cepat. Dengan beberapa (kecil?) Upaya tambahan (biaya) untuk programmer skrip shell.

  • Keamanan. Memiliki keragaman cangkang membantu ketahanan terhadap serangga. Sebagian besar sistem Debian tidak rentan terhadap shellshock karena shell default tidak memiliki kerentanan seperti itu.

Bash memang merupakan shell default untuk pengguna , karena lebih kuat dan memiliki lebih banyak elemen untuk membuat pengkodean lebih mudah. Ini juga merupakan default shdi Mac OS (yang ditautkan dari / bin / sh). Namun, panggilan bashdengan nama tautan shmembuatnya mulai sebagai shell yang sesuai dengan posix.


sumber
2
Satu set alat shell yang lebih sederhana yang tersedia lebih terbatas membuat penulisan kode lebih sulit (harap hindari perang fanatik terhadap ini). Itulah sebabnya beberapa pengguna menyukai zsh, yang bahkan memiliki lebih banyak alat daripada bash. Saya lebih suka Bash karena keseimbangan antara kedua ekstrem.
4
@RobertL, banyak fasilitas yang ditambahkan dalam ksh dan diadopsi oleh bash ada karena mereka secara substansial memudahkan proses penulisan skrip yang kuat dan benar. Tanpa berbagai penambahan yang memungkinkan penugasan dan evaluasi tidak langsung dilakukan dengan aman, misalnya, seseorang dapat menemukan dirinya menggunakan eval, dengan paparan keamanan yang menyertainya; sama halnya, tanpa dukungan regex bawaan, seseorang dapat perlu menggunakan perintah eksternal (dengan penalti performa yang berat) untuk mencocokkan bahkan dalam satu baris, dll.
Charles Duffy
1
@RuiFRibeiro, tidak ada yang terhubung secara statis di Debian. Dash lebih terbatas, tetapi terbatas terutama pada fitur interaktif (tanpa penyelesaian dan semacamnya) sehingga lebih cepat untuk skrip.
Jan Hudec
21

Yang lain telah menunjukkan bahwa premis pertanyaan, bahwa shell Bourne Again adalah default dan ada di mana-mana, benar-benar salah.

Selain itu, memang ada alasan bagus untuk menggunakan sesuatu selain shell Bourne Again untuk menafsirkan skrip shell. Alasan-alasan ini termotivasi Ubuntu dan proyek besar Debian, selama beberapa tahun, untuk menghapus bashisms dan untuk membuat sebagai banyak script shell yang dijalankan oleh inisialisasi sistem (yang merupakan banyak script shell dengan Sistem 5 rc) dan paket instalasi / penggunaan penghapusan tersebut Shell Debian Almquist, bukan shell Bourne Again.

Sederhananya: shell Bourne Again, penuh dengan fitur-fitur interaktif seperti itu, bukan penerjemah shell tercepat untuk skrip shell POSIX-conformant. Jadi jika seseorang dapat membuat skrip shell POSIX-conformant, menafsirkannya dengan program yang lebih ringan, seperti shell Debian Almquist, sistem seseorang akan berkinerja lebih baik. (Pada akhirnya, Debian harus membuat sedikit penyesuaian pada shell Almquist, untuk menambahkan dukungan untuk beberapa konstruksi shell non-POSIX yang terlalu dalam dan luas tertanam dan terlalu berguna untuk dihilangkan.)

Hasil dari semua itu adalah keuntungan besar dalam kinerja bootstrap.

Jadi ada dua kelas shell yang perlu dipertimbangkan, di sini:

  • Kerang dengan semua fitur interaktif mencolok, yang dikonfigurasikan sebagai kerang masuk interaktif untuk pengguna dalam basis data akun.
  • Kerang yang menafsirkan banyak skrip dengan cepat, yang digunakan sebagai penerjemah skrip oleh program skrip shell.

Perhatikan bahwa membicarakan ini sebagai "preferring /bin/sh" terlalu menyederhanakan. Debian sebenarnya memiliki setidaknya dua tujuan:

  1. Di hadapan administrator yang menggunakan shell Debian Almquist, Shell Z (dalam mode POSIX), shell Bourne Again (dalam mode POSIX), shell MirBSD Korn, dan lainnya seperti /bin/sh, ada salah satu…

    1. ... membuat skrip se portable mungkin, sehingga mengalihkan apa yang /bin/shdipetakan ke tidak merusak; atau

    2. ... membuat skrip non-portabel secara eksplisit menargetkan program interpreter yang benar , alih-alih hanya mengharapkan /bin/shpeta itu untuk itu.

  2. Ada membuat Debian Almquist shell pemetaan default untuk /bin/shbukan Bourne Shell, sehingga mereka skrip yang berada POSIX-konforman (atau, lebih tepat, Kebijakan Debian Pedoman conformant) berlari lebih cepat.

Dan tentu saja begitu seseorang masuk ke dalam ini, seseorang dapat mengambilnya lebih jauh; seperti mempertimbangkan efisiensi pengorbanan dari suka /bin/truedan /usr/bin/clearmenjadi skrip shell atau program yang disusun. Tapi untungnya itu di luar jangkauan jawaban ini. ☺

Tidak satu pun dari ini yang sangat baru, atau bahkan tidak spesifik-Unix, tentu saja. Kembali sebelum pergantian abad, saya menulis dan menerbitkan juru bahasa command-line yang datang dalam rasa "interaktif" dan "non-interaktif", menjelaskan pembagian ini dalam dokumennya dan mencatat perbedaan antara variabel lingkungan COMSPECdan OS2_SHELL. Demikian pula, diskusi tentang menghapus bashism di Sistem V Debian rcdan skrip instalasi / penghapusan paket kembali ke tahun 1990-an.

Bacaan lebih lanjut

JdeBP
sumber
2
"Pada akhirnya, Debian harus membuat sedikit penyesuaian pada cangkang Almquist, untuk menambah dukungan untuk beberapa konstruksi cangkang non-POSIX yang terlalu dalam dan luas tertanam dan terlalu berguna untuk dihilangkan." - Manakah dari banyak tautan Anda yang memiliki info tentang ini? Kedengarannya sangat menarik. :)
Wildcard
3
IMHO, kinerja hanyalah motivator untuk membuat orang menyetujui perubahan. Alasan utama awal untuk berubah adalah bahwa bash terus merusak kompatibilitas. Saya pribadi harus memperbaiki masalah bash setidaknya 3 kali dalam karier saya karena skrip akan berfungsi dalam satu versi bash tetapi gagal di versi lain (biasanya terjadi setelah peningkatan OS). Dash bukan hanya penerjemah yang sedikit lebih cepat. Itu juga jauh lebih stabil dalam hal perilaku.
slebetman
Saya akan tertarik apakah komentar di Schily Bourne Shellhalaman manual, lihat schilytools.sourceforge.net/bosh.html cocok untuk memungkinkan orang memahami cara menulis skrip portabel (yang hanya tergantung pada Bourne Shell featuresdari tahun 1989). Apa yang saya lakukan adalah menyebutkan setiap perangkat tambahan yang tidak ada di dalam Bourne Shells lama. BTW: Saya juga tertarik untuk mengetahui daftar bashisme di dasbor.
schily
8

Apakah ada alasan untuk meminta shebang menunjuk pada / bin / sh daripada / bin / bash?

Iya. @ Marco menjawab dengan sangat baik.

Apa yang harus saya gunakan di shebang saya?

Saat menulis skrip Anda sendiri, Anda harus mengarahkan shebang ke hal paling umum yang telah Anda uji.

Di sistem saya (Centos 6.6), shdisinkronkan dengan bash:

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Dec  2  2014 /bin/sh -> bash

Ini berarti bahwa saya selalu menggunakan #!/bin/bashshebang saya kecuali saya telah memverifikasi bahwa saya tidak memiliki bashims dalam skrip saya.

Dengan mengatur shebang untuk #!/bin/shAnda, menjanjikan bahwa script akan bekerja dengan semua implementasi sh.

Ini adalah janji yang jauh lebih besar daripada mengatakan bahwa skrip akan bekerja dengan bash.

Berikut adalah contoh skrip yang akan berperilaku tidak benar tergantung pada shimplementasi yang digunakan sistem:

#!/bin/sh
n=1
a=$((++n))
echo $n

Saat menggunakan bashskrip akan mencetak:

2

Saat menggunakan dashskrip akan mencetak:

1

Jika saya ingin menggunakan #!/bin/shapa yang harus saya lakukan?

  • Periksa skrip dengan checkbashisms- Perhatikan bahwa ini tidak akan menemukan semua bashims. Tidak menemukan bashism di skrip saya di atas
  • Uji skrip menggunakan shimplementasi lain . Saya biasanya menguji dengan dash, namun saya berharap bahwa beberapa bashism atau dashims masih bisa lolos.

The halaman DashAsBinSh di wiki Ubuntu memiliki banyak info yang menarik.

sixtyfootersdude
sumber
6
"Saat menulis skrip Anda sendiri, Anda harus mengarahkan shebang ke hal paling umum yang telah Anda uji terhadap .... Dengan mengatur shebang ke #! / Bin / sh Anda berjanji bahwa skrip akan bekerja dengan semua implementasi shebang . " Baik titik. +1, dan Anda telah membuat saya memikirkan kembali bagaimana saya akan menulis shebangs saya untuk masa depan. Terima kasih! :)
Wildcard
2
Nah, tidak semua implementasi /bin/sh; hanya yang sesuai dengan POSIX.
Blacklight Shining
4

Satu-satunya alasan yang tersisa untuk menulis skrip shell, alih-alih skrip dalam bahasa yang lebih kuat dan ergonomis, adalah jika portabilitas ke sistem lama dengan serangkaian perangkat lunak yang diinstal tidak diketahui lebih penting daripada faktor lainnya .

/bin/shadalah satu-satunya penerjemah skrip yang tersedia untuk semua yang menyebut dirinya Unix. Tetapi pada banyak sistem warisan, /bin/shdan utilitas yang terkait bahkan tidak sesuai dengan spesifikasi "shell and utility" POSIX.1-1996, apalagi yang lebih modern. Alat yang memenuhi standar adalah tambahan opsional, dipasang di /usr/xpg4atau beberapa lokasi yang tidak jelas. 1 Menulis skrip ke bahasa shell subset portabel bahkan lebih membosankan dan rentan kesalahan daripada skrip ke bahasa shell POSIX. (Baca configureskrip yang dibuat Autoconf kapan saja jika Anda tidak percaya. Hanya pengaturannya yang cukup untuk meyakinkan Anda.)

Tetapi jika Anda dapat menganggap juru bahasa skrip lain diinstal (misalnya Bash) maka Anda dapat menganggap juru bahasa untuk bahasa skrip yang lebih baik telah diinstal. Perl, misalnya, lebih mungkin tersedia daripada Bash.

Karena itu, Anda tidak boleh menulis #! /bin/bashskrip, karena jika itu pilihan, bahasa yang lebih baik juga merupakan pilihan.

1 Misalnya, Solaris 10 dan yang lebih lama mengirimkan shell Bourne asli sebagai /bin/sh. Saya diberitahu bahwa Solaris 11 memperbaruinya ke ksh93.

zwol
sumber
3
Dalam bahasa apa Anda akan menulis skrip untuk mem-boot sistem? Atau di dalam router SOHO (sistem embebed terbatas)? Atau di Android? Shell akan tersedia dalam semua kasus itu. Perl tidak.
1
Ada beberapa ketidakakuratan tentang bagian terkait Solaris dari jawaban Anda. Pada Solaris 10 dan lebih tua, /bin/shadalah tidak POSIX.1-1996 tetapi sebenarnya pra-POSIX sintaks asli shell Bourne. Itu membuat #!/bin/shshebang yang sangat buruk untuk menjalankan skrip dengan rilis ini. Skrip portabel pada Solaris akan digunakan #!/usr/xpg4/bin/shyang tidak akan terlalu portabel pada OS lain. Pada Solaris terbaru, Oracle Solaris 11 pertama kali dirilis 2011, /bin/shadalah yang modern ksh93yang sesuai dengan spesifikasi POSIX terbaru, dan memiliki banyak ekstensi modern.
jlliagre
1
@ Binzebra: "A shell" akan tersedia, ya. Tapi bash belum tentu shell itu (khususnya sebagian besar router SOHO menggunakan ashyang disediakan dengan busybox), dan saya cenderung berpikir zwol benar bahwa perl lebih umum tersedia daripada bash.
Ben Voigt
1
@ BenVoigt Saya mengomentari kalimat ini "Satu-satunya alasan untuk menulis skrip shell". Masih ada beberapa contoh yang membutuhkan shell untuk beberapa tugas (tidak semua). Itu adalah beberapa contoh dari kepala saya. OTOH Dalam sistem dengan memori yang cukup (hampir semua dalam standar saat ini) dan cukup daya menginstal Perl (atau Python, atau ....) cukup cepat dan mudah. Namun, saya tidak menganjurkan untuk shell tertentu. Di mana Anda membacanya dalam komentar saya?
2
Tidak setuju sepenuhnya dengan klaim Anda yang sangat beralasan dan non-faktual bahwa "jika bashtersedia maka bahasa yang lebih baik sehingga Anda tidak boleh menulis bashkode apa pun ." Juga, seperti yang ditunjukkan oleh @sixtyfootersdude, Anda harus selalu menggunakan #!/bin/bashkecuali Anda telah menguji bahwa skrip Anda berfungsi dengan semua shell POSIX.
Wildcard
0

Anda harus benar-benar menggunakan keduanya

#! /bin/env sh

atau

#! /bin/env bash

dengan cara itu Anda memanggil shell dengan cara mereka menginstal pada sistem itu.

Agar sangat aman ( mis. Dalam kasus reboot satu pengguna) gunakan shsebaliknya gunakan bash.

Paul Evans
sumber
6
Dari jawaban ini : the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.Ini mungkin juga berlaku untuk shdan bash.
Jules
12
Tidak, Anda tidak boleh menggunakan #!/bin/envapa pun dalam skrip portabel. Sangat masuk akal untuk berasumsi bahwa itu /bin/shada dan berfungsi, shell yang sesuai dengan POSIX. Di sisi lain, tidak ada sistem saya yang punya /bin/env.
Blacklight Shining
Poin yang bagus juga.
Jules
1
@ Blacklight Bersinar jelas salah untuk menganggap shell yang sesuai dengan POSIX /bin/sh. POSIX tidak memerlukannya dan lebih tepatnya mendefinisikan aturan lain untuk mendapatkan lingkungan yang sesuai dengan POSIX pada platform bersertifikat POSIX.
schily
4
/usr/bin/envtidak tersedia secara universal ...
vonbrand