Ketika sh adalah symlink ke bash atau dash, bash membatasi dirinya sendiri untuk kepatuhan POSIX, jadi itu harus 100% kompatibel dengan sh?

8

Dari Perbedaan antara bash dan sh :

Abaikan pertanyaan: Jika Anda memiliki /bin/shtautan ke bash, maka bash tidak akan berperilaku sama ketika dipanggil seperti /bin/shhalnya ketika dipanggil sebagai /bin/bash. Ketika dipanggil sebagai sh, itu akan membatasi dirinya untuk sebagian besar kepatuhan POSIX plus satu set ekstensi terbatas.

Apakah ini berarti bahwa setiap kali saya menemukan skrip shell di Linux dengan shebang to sh:, #!/bin/shbahkan jika pada distro itu, bin/shadalah symlink ke shell lain, seperti dash atau bash, itu harus 100% kompatibel dengan bourne shell, karena itu membatasi dirinya untuk satu set ekstensi terbatas? Jadi saya bisa menjalankannya di FreeBSD? Apakah ada pengecualian untuk itu? Atau saya harus aman untuk berasumsi bahwa itu akan berhasil?

Jadi jika pada distro, bin/shapakah symlink bin/bash, dan skrip menggunakan #!/bin/shdan skrip berisi bashism, itu tidak akan berjalan, karena bash akan suka berada dalam mode sh?

pengguna1115057
sumber

Jawaban:

16

Tidak, jika /bin/shsymlink ke bash bash memasuki mode posix saja - dari man bash :

Ketika dipanggil sebagai sh, bash memasuki mode posix setelah file startup dibaca.

Jika sekarang Anda mencari mode posix di bash manpage Anda akan melihat bahwa beberapa shell bawaan menyukai timeatau sourceberperilaku berbeda. Itu semuanya. bashishms seperti menulis functionsebelum mendeklarasikan suatu fungsi atau menggunakan sourcealih-alih .masih akan bekerja tetapi perintah mungkin berperilaku berbeda.

Jadi jika /bin/shsymlink ke /bin/bashsemua bashishms khas masih berfungsi.

Untuk daftar perbedaan yang cukup luas dalam mode Posix lihat manual referensi bash .

Ulrich Dangel
sumber
Jadi saya kira hal terbaik yang harus dilakukan adalah menguji semua skrip di alat checkbashism. Saya mendengar bahwa beberapa distro, seperti Debian dan Ubuntu (perlu konfirmasi untuk yang satu ini) sudah memiliki symlink bin / sh mereka sekarang. Apakah tanda hubung kompatibel dengan shell bourn? Jika ya, maka setidaknya semua skrip shell Debian dan Ubuntu harus baik-baik saja di bawah FreeBSD.
user1115057
@ user1115057 hanya skrip shell dengan /bin/shsebagai shebang. Script shell masih dapat digunakan secara eksplisit /bin/bash. Bagaimanapun sebagian besar skrip shell mungkin akan berjalan dengan baik di bawah / bin / sh tetapi masalahnya adalah alat pengguna, misalnya kebanyakan skrip shell mengharapkan GNU userland yang mungkin akan lebih menjadi masalah daripada hanya beberapa kesalahan sintaksis. Saya juga menambahkan tautan ke referensi bash yang mencantumkan perilaku yang berbeda dalam mode
posix
Ok dari yang saya baca, BSD menggunakan ash sebagai bin / sh mereka, sedangkan Debian & Ubuntu menggunakan dash. Jika shell itu kompatibel, itu berarti saya tidak akan lagi memiliki masalah dengan shebang #! / Bin / sh. Tapi seperti yang Anda katakan, akan ada masalah lain yang terkait dengan pengguna ...
user1115057
@ dasbor user1115057 juga tidak sempurna, misalnya wiki.ubuntu.com/DashAsBinSh/#echo toh sebagian besar skrip shell agak sederhana dan dapat diangkut dengan mudah ... semoga berhasil
Ulrich Dangel
Tapi dash dan ash kompatibel kan?
user1115057
8

Tampaknya ada beberapa kebingungan di sekitar kulit Bourne. Shell Bourne adalah shell Unix beberapa dekade yang lalu, pada masa pra-POSIX. Saat ini "sh" adalah implementasi atau yang lain dari shell yang mengimplementasikan spesifikasi POSIX, di antaranya kami memiliki bash, pdksh, AT&T ksh, shell Almquist yang lebih baru dan turunannya yang telah dibuat sesuai dengan POSIX (termasuk "sh" dari beberapa BSDs , BSD lain yang didasarkan pada pdksh dan abu Debian (tanda hubung)). Bahkan zsh memiliki mode yang sebagian besar sesuai dengan POSIX.

Shell Bourne tidak kompatibel dengan POSIX, dan tidak dapat ditemukan di banyak sistem saat ini. Di mana shell Bourne ditemukan atau di mana tidak, selalu akan ada "sh" yang sesuai dengan POSIX (dan tidak akan menjadi shell Bourne), umumnya /binsementara pengecualian yang menonjol (menjengkelkan) adalah Solaris.

Perhatikan bahwa sebelum shell Bourne, dan kita berbicara lebih dari 30 tahun yang lalu, "sh" adalah shell Thompson. Kami tidak lagi menulis skrip yang kompatibel dengan shell Thompson. Demikian pula, kita harus berhenti menganggap "sh" sebagai cangkang Bourne.

Sekarang "sh" adalah spesifikasi, tidak banyak varian implementasi yang tidak kompatibel. Itu membuatnya jauh lebih mudah untuk menulis skrip portabel. Ikuti saja spesifikasinya .

Itu berlaku untuk "sh" dan semua utilitas standar (sed, cut, tr ...)

Stéphane Chazelas
sumber
+1 untuk "tulis sesuai spesifikasi." Tapi sayangnya itu sering tidak cukup untuk portabilitas. Sebagai contoh, bagaimana jika seseorang ingin menggunakan pola gaya egrep di sed? Spesifikasi tidak menyediakan untuk ini. Pada sistem dengan utilitas berbasis Gnu (atau BusyBox), Anda gunakan sed -r. Pada sistem dengan utilitas berbasis BSD, Anda gunakan sed -E. FreeBSD's sed menerima keduanya, tetapi Mac OS X hanya menerima -E. Dan seterusnya dan seterusnya.
dubiousjim
Itu intinya. Spesifikasi tidak menyediakannya, jadi Anda tidak dapat menggunakannya dengan mudah / POSIXly. Jika Anda menggunakan BRE, yang akan bekerja pada semua sistem yang sesuai dengan POSIX, itu adalah jaminan yang diberikan oleh POSIX, itu sebabnya ini berguna. Di luar POSIX seperti yang Anda katakan, tidak ada harapan karena seds tidak mendukung ERE atau mendukungnya dengan opsi yang berbeda atau sintaks ERE yang berbeda. Perhatikan bahwa ERE kurang mampu daripada BRE (hanya sintaks yang diperluas dalam ERE untuk menghemat beberapa pengetikan. ERE dapat diterjemahkan ke BRE, sebaliknya tidak benar (BRE \(...\)\1tidak memiliki terjemahan dalam ERE standar).
Stéphane Chazelas
1
Saya menyadari bahwa (POSIX) EREs kekurangan referensi belakang; sebenarnya saya sudah berpartisipasi dalam mengedit bagian standar itu. Tidaklah benar bahwa POSRE EREs benar-benar kurang mampu daripada BREs, karena dalam standar saat ini, pergantian tidak ditentukan untuk BREs. Namun, saya tidak mengetahui adanya mesin regex yang tidak menghormati \|BRE. Saya semua untuk menulis portable mungkin. Saya hanya melakukan pengamatan (saya pikir sangat dihargai) bahwa ini bisa menyakitkan, dan kadang-kadang menulis ke POSIX sama sekali tidak mungkin. Di suatu tempat ada tautan yang menunjukkan banyak penyimpangan seperti itu; akan mencari mereka.
dubiousjim
Poin bagus tentang pergantian, saya lupa tentang itu dan berdiri dikoreksi. Dengan sed, tidak mungkin untuk memblokir karena Anda dapat menggunakan beberapa ekspresi untuk mencocokkan regexps alternatif. Ada awam dalam toolchest standar yang dapat digunakan jika ERE diperlukan. Saya sangat jarang menemukan diri saya dengan toolchest standar, dan ketika saya melakukannya, itu umumnya kasus di mana bahasa lain seperti perl lebih tepat, tetapi saya memang melihat maksud Anda (meskipun saya masih berpikir itu di samping intinya di thread ini tentang menulis skrip portabel)
Stéphane Chazelas
Contoh yang saya pikirkan begitu saja: baris shebang (di bagian atas setiap skrip shell) tidak ditentukan dalam POSIX. Juga, saya tidak yakin saya pernah menggunakan sistem yang 100% mendukung POSIX. Misalnya, POSIX mengatakan Anda dapat memasukkan baris baru di dalam ${VAR:=stuff...here}tetapi banyak shell tidak membiarkan Anda, Anda harus memberi tanda kutip stuff...here.
dubiousjim