Saya telah membaca yang berikut dalam pertanyaan ini :
bash mendukung switch --posix, yang membuatnya lebih sesuai dengan POSIX. Itu juga mencoba untuk meniru POSIX jika dipanggil sebagai sh .
Kutipan di atas mengasumsikan bahwa itu /bin/sh
adalah tautan yang menunjuk /bin/bash
.
Tapi saya tidak begitu mengerti apa yang dimaksud dengan "dipanggil sebagai sh" .
Katakan bahwa saya memiliki skrip berikut yang disebut "script.sh":
#!/bin/bash
echo "Hello World"
Tolong beri tahu saya dalam setiap kasus berikut apakah skrip akan dijalankan dalam bash
mode normal atau dalam mode POSIX (asumsikan bahwa saya telah menjalankan perintah berikut di terminal yang sedang berjalan bash
):
sh script.sh
bash script.sh
./script.sh
Sekarang katakan bahwa saya memiliki skrip berikut yang disebut "script.sh" (yang seperti skrip di atas tetapi tanpa shebang):
echo "Hello World"
Tolong beri tahu saya dalam setiap kasus berikut apakah skrip akan dijalankan dalam bash
mode normal atau dalam mode POSIX (asumsikan bahwa saya telah menjalankan perintah berikut di terminal yang sedang berjalan bash
):
sh script2.sh
bash script2.sh
./script2.sh
Jawaban:
Hanya case 1 & 4 yang akan berjalan dalam mode POSIX (dengan asumsi itu
sh
adalah bash dan bukan implementasi sh lainnya). Kasus apa pun yang secara eksplisit meneleponbash
tanpa--posix
tidak akan, apakah dari shebang atau tidak. Kasus apa pun yang secara eksplisit meneleponsh
akan. Shebang hanya digunakan ketika tidak ada shell yang secara eksplisit dimulai untuk skrip.Kasus 6, jika terminal Anda berjalan
bash
, tidak akan berjalan dalam mode POSIX dan Bash akan menggunakannya dengan sendirinya. Jika terminal Anda menjalankan zsh, case 6 juga akan berjalan dalam mode POSIX. POSIX tidak jelas tentang apa yang seharusnya terjadi dalam kasus itu , dan Bash dan zsh membuat pilihan berbeda di sana. Bash memanggil script menggunakan dirinya sendiri, sementara zsh menggunakansh
(apa pun yang terjadi). Kerang lain juga bervariasi pada titik itu.Salah satu cara sederhana untuk mengetahui mode apa yang Anda gunakan adalah membuat badan skrip:
yang akan gagal dengan kesalahan dalam mode POSIX , tetapi memberikan instruksi penggunaan untuk di
kill
luar itu. Ini adalah perbedaan yang mudah dan berfungsi melalui sejumlah besar versi Bash yang akan kembali sejauh yang mungkin Anda temui.sumber
bash
untuk dijalankan dalam mode POSIX sepertiPOSIXLY_CORRECT
variabel lingkungan atauSHELLOPTS=posix
.[ -o posix ]
adalah cara yang lebih jelas untuk memeriksa bahwa Anda menjalankan dalam mode posix di bash (bukan di shell lain (kecuali yash), jadi Anda tidak ingin melakukannya dalamsh
skrip).POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'
keluaranyes
`"Dipanggil sebagai" mengacu pada apa pun itu bahwa proses mulai Bash menempatkan dalam argumen baris perintah "nol"
argv[0]
,.Ketika sebuah program dimulai dengan
exec*()
syscalls , mereka tidak benar-benar mengetahui nama file biner yang berisi program tersebut, tetapi sebaliknya proses panggilan bebas untuk meletakkan apa pun yang diinginkan di sana. Biasanya, tentu saja, nama tersebut diambil dari sistem file, jadi jika Anda menjalankannya/bin/sh
, itulah yang akan dimasukkan ke sana. Dan jika/bin/sh
Bash, itu tidak harus symlink, itu bisa berupa tautan keras atau hanya salinan lain dari program shell.Sebagai contoh pengaturan "nama program",
exec
perintah Bash dapat mengatur argumen nol dengan-a
opsi. (Kita bisa melakukan hal yang sama dengan Perl, atau langsung dengan C, dll.)Di sini,
myname
adalah program C sederhana yang hanya mencetak argumen nolnya, nama yang dilihatnya sendiri:Sumber:
Tapi, untuk menjawab pertanyaan bernomor ...
(1 & 4) menjalankan
sh somescript
akan menjalankan apa pun yangsh
ada di AndaPATH
, mungkin/bin/sh
tetapi mungkin sesuatu seperti/usr/xpg4/bin/sh
.sh
.sh
, tetapi ia berjalan dalam mode "SH kompatibel", yang bertujuan untuk menjadi kompatibel dengan shell Bourne dan agak berbeda dengan mode konforman POSIX penuh di kedua shell tersebut. .(2 & 5) Menjalankan
bash somescript
akan berjalan dalam mode Bash biasa (sekali lagi, tentu saja tergantung pada apa yang adabash
di AndaPATH
.)(3) Di sini, nama skrip diberikan langsung ke pemanggilan sistem menggantikan file program. Kernel membaca baris hashbang dan menggunakannya untuk menjalankan skrip.
(6) Ini yang kompleks. Ini mirip dengan (3), tetapi panggilan sistem untuk memulai program gagal (
ENOEXEC (Exec format error)
), karena tidak ada garis hashbang. Apa yang terjadi selanjutnya tergantung dari apakah shell yang Anda jalankan sendiri dalam mode POSIX. POSIX mensyaratkan bahwa shell yang sesuai dengan POSIX berperilaku dengan cara tertentu sebagai respons terhadapENOEXEC
. Namun, ada beberapa kelonggaran dalam "perintah yang setara dengan membuat shell dipanggil" yang berarti bahwa shell berbeda melakukan hal yang berbeda./bin/sh
dengan nama skrip yang dimasukkan sebelum argumen lain sebagai argumen baris perintah pertama. Cangkang Z, cangkang Almquist, dan cangkang Korn sedang (mencoba) untuk memanggil cangkang yang sesuai dengan POSIX dengan tidak berasumsi bahwa/bin/sh
programnya adalah satu.sumber
int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
Shell dieksekusi adalah salah satu yang disebut pada command line atau satu peristiwa (jika baris perintah tidak menentukan itu).
Jadi, versi 1 dan 4 akan berjalan dengan
sh
, 2 dan 5 dengan bash dan 6 mungkin tidak berjalan jika Anda menggunakan sh (dan beberapa yang lain) secara interaktif. Bash memulai skrip. Ksh juga. Zsh memulainya sebagai sh.Hanya yang memulai yang
sh
akan menggunakan opsi posix jika bash ditautkan ke/bin/sh
.Tambahkan baris ini ke skrip Anda untuk mendeteksi jika ada versi bash ksh atau zsh yang menjalankannya:
sumber