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/sh
lebih /bin/bash
, karena bash
cukup banyak di mana-mana, dan sering default, pada banyak mesin Linux dan BSD kembali lebih dari satu dekade?
/bin/sh
jika Anda tidak menggunakanbash
fungsi tertentu . Suatu hari Anda bisa menggunakan salah satu skrip Anda pada sistem yang tidak diinstal (server jarak jauh, komputer yang disematkan ...)...the answers so far are fairly subjective...
Pernyataan "subyektif" pada dasarnya didasarkan pada definisi./bin/bash
seharusnya hanya digunakan ketika bash secara eksplisit diperlukan. Dalam 40+ tahun sebagai pengembang, jauh sebelumnyabash
, 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.Jawaban:
/bin
.sumber
/bin/sh
lebih cepat jika tidakbash
, masih ada beberapa sistem seperti OS / X atau RHEL mana/bin/sh
adalahbash
./bin/sh
adalah/bin/bash
. Perpindahan Ubuntu dari bash ke dash merusak semuanya.#!/bin/bash
jika 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".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
sh
di Mac OS (yang ditautkan dari / bin / sh). Namun, panggilanbash
dengan nama tautansh
membuatnya mulai sebagai shell yang sesuai dengan posix.sumber
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.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:
Perhatikan bahwa membicarakan ini sebagai "preferring
/bin/sh
" terlalu menyederhanakan. Debian sebenarnya memiliki setidaknya dua tujuan: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…... membuat skrip se portable mungkin, sehingga mengalihkan apa yang
/bin/sh
dipetakan ke tidak merusak; atau... membuat skrip non-portabel secara eksplisit menargetkan program interpreter yang benar , alih-alih hanya mengharapkan
/bin/sh
peta itu untuk itu.Ada membuat Debian Almquist shell pemetaan default untuk
/bin/sh
bukan 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/true
dan/usr/bin/clear
menjadi 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
COMSPEC
danOS2_SHELL
. Demikian pula, diskusi tentang menghapus bashism di Sistem V Debianrc
dan skrip instalasi / penghapusan paket kembali ke tahun 1990-an.Bacaan lebih lanjut
/bin/sh
. Wiki Ubuntu./bin/sh
. Wiki Debian.sumber
Schily Bourne Shell
halaman manual, lihat schilytools.sourceforge.net/bosh.html cocok untuk memungkinkan orang memahami cara menulis skrip portabel (yang hanya tergantung padaBourne Shell features
dari 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.Iya. @ Marco menjawab dengan sangat baik.
Saat menulis skrip Anda sendiri, Anda harus mengarahkan shebang ke hal paling umum yang telah Anda uji.
Di sistem saya (Centos 6.6),
sh
disinkronkan denganbash
:Ini berarti bahwa saya selalu menggunakan
#!/bin/bash
shebang saya kecuali saya telah memverifikasi bahwa saya tidak memiliki bashims dalam skrip saya.Dengan mengatur shebang untuk
#!/bin/sh
Anda, menjanjikan bahwa script akan bekerja dengan semua implementasish
.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
sh
implementasi yang digunakan sistem:Saat menggunakan
bash
skrip akan mencetak:Saat menggunakan
dash
skrip akan mencetak:Jika saya ingin menggunakan
#!/bin/sh
apa yang harus saya lakukan?checkbashisms
- Perhatikan bahwa ini tidak akan menemukan semua bashims. Tidak menemukan bashism di skrip saya di atassh
implementasi lain . Saya biasanya menguji dengandash
, namun saya berharap bahwa beberapa bashism atau dashims masih bisa lolos.The halaman DashAsBinSh di wiki Ubuntu memiliki banyak info yang menarik.
sumber
/bin/sh
; hanya yang sesuai dengan POSIX.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/sh
adalah satu-satunya penerjemah skrip yang tersedia untuk semua yang menyebut dirinya Unix. Tetapi pada banyak sistem warisan,/bin/sh
dan 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/xpg4
atau 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. (Bacaconfigure
skrip 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/bash
skrip, 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.sumber
/bin/sh
adalah tidak POSIX.1-1996 tetapi sebenarnya pra-POSIX sintaks asli shell Bourne. Itu membuat#!/bin/sh
shebang yang sangat buruk untuk menjalankan skrip dengan rilis ini. Skrip portabel pada Solaris akan digunakan#!/usr/xpg4/bin/sh
yang tidak akan terlalu portabel pada OS lain. Pada Solaris terbaru, Oracle Solaris 11 pertama kali dirilis 2011,/bin/sh
adalah yang modernksh93
yang sesuai dengan spesifikasi POSIX terbaru, dan memiliki banyak ekstensi modern.ash
yang disediakan dengan busybox), dan saya cenderung berpikir zwol benar bahwa perl lebih umum tersedia daripada bash.bash
tersedia maka bahasa yang lebih baik sehingga Anda tidak boleh menulisbash
kode apa pun ." Juga, seperti yang ditunjukkan oleh @sixtyfootersdude, Anda harus selalu menggunakan#!/bin/bash
kecuali Anda telah menguji bahwa skrip Anda berfungsi dengan semua shell POSIX.Anda harus benar-benar menggunakan keduanya
atau
dengan cara itu Anda memanggil shell dengan cara mereka menginstal pada sistem itu.
Agar sangat aman ( mis. Dalam kasus reboot satu pengguna) gunakan
sh
sebaliknya gunakanbash
.sumber
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 untuksh
danbash
.#!/bin/env
apa pun dalam skrip portabel. Sangat masuk akal untuk berasumsi bahwa itu/bin/sh
ada dan berfungsi, shell yang sesuai dengan POSIX. Di sisi lain, tidak ada sistem saya yang punya/bin/env
./bin/sh
. POSIX tidak memerlukannya dan lebih tepatnya mendefinisikan aturan lain untuk mendapatkan lingkungan yang sesuai dengan POSIX pada platform bersertifikat POSIX./usr/bin/env
tidak tersedia secara universal ...