Cara menggunakan Bash untuk sh di Ubuntu

13

Saya menginstal program besar, yang memiliki sumber dayanya sebagai rpmfile. Itu terjebak di garis

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Rupanya, shbekerja untuk bashdi Red Hat Linux dengan sintaks ini, tetapi memberikan kesalahan unexpected operatordi Ubuntu.

Saya tidak dapat mengubah skrip bashkarena skrip berasal dari rpmpaket. Saya dapat mengekstrak dan mengemas ulang rpmpaket tersebut, tetapi mungkin ada banyak skrip seperti itu.

Apakah ada cara untuk mengubah shell default untuk diperlakukan #!/bin/shsebagai bashatau apa pun, yang dapat menangani [operator?

Googlebot
sumber
5
Satu-satunya yang salah adalah ==yang seharusnya =. Itu, dan bahwa ekspansi variabel harus dikutip ganda.
Kusalananda
4
[bukan operator, tetapi perintah builtin yang dipanggil test. Operator yang tidak terduga adalah ==dan ini harus diganti oleh =karena tidak sesuai dengan POSIX.
schily
Satu-satunya hal kedua yang salah adalah yang $SCITEGICPERLHOMEharus dikutip.
l0b0
12
Anda harus mengeluh kepada penulis program. Jika mereka menggunakan #!/bin/sh, mereka harus memastikan mereka hanya menggunakan fitur shell POSIX, bukan bashekstensi. Programmer ini sangat ceroboh. Dia harus memperbaiki kodenya atau menggunakannya #!/bin/bash.
Barmar
Untuk orang yang bertanya-tanya tentang masalah serupa lainnya di sini adalah daftar " Bashisms ". Lihat juga pertanyaan ini .
Kapten Man

Jawaban:

21

Ada beberapa program yang mengimplementasikan bahasa /bin/sh. Di Ubuntu, /bin/shadalah dash, yang dirancang untuk menjadi cepat, untuk menggunakan sejumlah kecil memori, dan tidak mendukung lebih dari yang diharapkan /bin/sh. Di RHEL, /bin/shadalah bash, yang lebih lambat dan menggunakan lebih banyak memori tetapi memiliki lebih banyak fitur. Salah satu fitur ini adalah ==operator untuk [sintaksis bersyarat. Dukungan Dash [, yang merupakan fitur sh dasar, tetapi tidak memiliki ==operator yang merupakan ekstensi bash (dan ksh dan zsh).

Anda dapat mengganti sistem Anda untuk menggunakan bash. Di Ubuntu, /bin/shadalah tautan simbolis ke dash. Anda dapat menjadikannya sebagai tautan simbolis bash. Versi Debian dan Ubuntu saat ini (dan turunannya) menjadikan ini opsi pemasangan dasbor. Untuk mengubahnya, jalankan

sudo dpkg-reconfigure dash

dan jawab "ya" untuk tetap berlari sebagai /bin/shatau "tidak" untuk beralih ke bash.

Anda dapat menyimpan bash sebagai /bin/sh, tetapi itu akan membuat sistem Anda sedikit lebih lambat. Bahkan dapat dibayangkan bahwa beberapa skrip sistem tidak kompatibel dengan bash, walaupun itu tidak mungkin karena bash sebagian besar adalah superset dari dash.


Untuk distribusi yang tidak memiliki antarmuka untuk memilih antara implementasi /bin/sh, berikut ini cara beralih ke bash.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Biarkan terminal terbuka dan periksa apakah Anda masih dapat menjalankan beberapa shskrip setelah itu. Jika Anda mengacaukan perintah ini, itu akan membuat sistem Anda tidak dapat digunakan. (Ngomong-ngomong, alasan saya menggunakan banyak perintah di atas daripada yang terlihat langsung sudo ln -sf bash /bin/shadalah karena ln -sfitu bukan atom. Dalam kasus yang tidak disangka komputer Anda mengalami crash selama operasi ini, Anda harus mem-boot dari media cadangan untuk memulihkannya. Sebaliknya, mvadalah atomik.)

Untuk mengembalikan tanda hubung sebagai /bin/sh:

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Perhatikan bahwa jika sh secara /bin/bashdefault pada distribusi Anda, beralih ke tanda hubung dapat menyebabkan skrip gagal, karena bash memiliki lebih banyak fitur daripada tanda hubung. Skrip Bash harus dimulai dengan #!/bin/bash, dan skrip dimulai dengan #!/bin/shtidak boleh menggunakan fitur spesifik bash, tetapi distribusi yang dikirimkan dengan bash /bin/shmungkin menggunakan fitur spesifik bash dalam #!/bin/shskrip yang khusus untuk distribusi itu (tidak apa-apa asalkan tidak ada harapan bahwa pengguna dapat beralih ke dasbor karena /bin/shdan tidak ada harapan bahwa skrip ini berfungsi pada distribusi lain).

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Menurut pendapat saya yang tidak begitu rendah hati, jika beberapa skrip gagal ketika /bin/shBash, itu adalah bug baik dalam sistem (paket dengan skrip), atau dalam sh-mode Bash . Seperti kata Stephen, sistem secara eksplisit memungkinkan untuk mengatur /bin/shkembali ke Bash, via dpkg-reconfigure. Ini juga disebutkan sebagai kemungkinan dalam wiki Ubuntu dalam hal ini: wiki.ubuntu.com/DashAsBinSh
ilkkachu
5
@ilkkachu Ya, jika skrip gagal jika /bin/shbash, ini adalah bug. Namun, bug terjadi. Saya sarankan tetap menggunakan default jika Anda tidak mampu dan mau mendiagnosis bug tersebut karena orang lain telah mengujinya untuk Anda. Saya menggunakan tanda hubung seperti /bin/shsebelumnya secara resmi didukung pada Debian, tetapi ini adalah risiko yang saya ambil, tahu bahwa saya dapat mengatasinya jika sesuatu terjadi.
Gilles 'SO- stop being evil'
Perhatikan bahwa symlink yang ditimpa secara manual akan dikembalikan ke konfigurasi apa pun yang disimpan di debconfwaktu berikutnya dashdiperbarui; harus diakui ini tidak akan sering terjadi (jika sama sekali, dalam rilis yang diberikan) untuk sistem yang menjalankan Debian stable.
Stephen Kitt
36

Untuk beralih shke bash(alih-alih dash, default), konfigurasi ulang dash(ya, ini agak kontra-intuitif):

sudo dpkg-reconfigure dash

Ini akan menanyakan apakah Anda ingin dashmenjadi shell sistem default; jawab "Tidak" ( Tablalu Enter) danbash akan menjadi default sebagai gantinya ( yaitu /bin/sh akan menunjuk ke /bin/bash).

Stephen Kitt
sumber
1
Solusi Anda memang yang paling masuk akal, tetapi saya menerima jawaban lain karena deskripsi terperinci mengklarifikasi masalah ini. Maaf untuk ketidaknyamanan.
Googlebot
@Googlebot tidak perlu meminta maaf, memilih jawaban yang diterima adalah hak istimewa si penanya. Dan saya mendapat lencana emas darinya ;-).
Stephen Kitt