Dari halaman Bahasa Perintah Shell dari spesifikasi POSIX:
Jika baris pertama file perintah shell dimulai dengan karakter "#!", Hasilnya tidak ditentukan.
Mengapa perilaku yang #!
tidak ditentukan oleh POSIX? Saya merasa bingung bahwa sesuatu yang begitu portabel dan banyak digunakan akan memiliki perilaku yang tidak ditentukan.
exec()
fungsi. Jadi memeriksa beberapa shell tidak benar-benar memberitahu Anda seberapa portabelnya.Jawaban:
Saya pikir terutama karena:
perilaku sangat bervariasi antara implementasi. Lihat https://www.in-ulm.de/~mascheck/various/shebang/ untuk semua detailnya.
Namun sekarang bisa menentukan subset minimum dari sebagian besar implementasi mirip Unix: seperti
#! *[^ ]+( +[^ ]+)?\n
(dengan hanya karakter dari karakter nama file portabel yang diatur dalam satu atau dua kata) di mana kata pertama adalah jalur absolut ke executable asli, masalahnya tidak terlalu lama dan perilaku tidak ditentukan jika executable adalah setuid / setgid, dan implementasinya ditentukan apakah jalur juru bahasa atau jalur skrip diteruskanargv[0]
ke juru bahasa.POSIX tidak menentukan jalur yang dapat dieksekusi. Beberapa sistem memiliki utilitas pra-POSIX di
/bin
//usr/bin
dan memiliki utilitas POSIX di tempat lain (seperti pada Solaris 10 di mana/bin/sh
terdapat Bourne shell dan yang POSIX ada di/usr/xpg4/bin
dalamnya; Solaris 11 menggantinya dengan ksh93 yang lebih sesuai dengan POSIX, tetapi sebagian besar yang lain alat di/bin
masih yang non-POSIX kuno). Beberapa sistem bukan yang POSIX tetapi memiliki mode / emulasi POSIX. Semua POSIX memerlukan adalah bahwa ada lingkungan yang terdokumentasi di mana sistem berperilaku POSIXly.Lihat Windows + Cygwin misalnya. Sebenarnya, dengan Windows + Cygwin, she-bang dihormati ketika skrip dipanggil oleh aplikasi cygwin, tetapi tidak oleh aplikasi Windows asli.
Jadi, bahkan jika POSIX menentukan mekanisme shebang, ia tidak dapat digunakan untuk menulis skrip POSIX
sh
/sed
/awk
... (juga perhatikan bahwa mekanisme shebang tidak dapat digunakan untuk menulis skripsed
/ dapat diandalkanawk
karena tidak mengizinkan melewati opsi akhir opsi penanda).Sekarang fakta bahwa itu tidak ditentukan tidak berarti Anda tidak dapat menggunakannya (well, ia mengatakan Anda tidak harus memulai dengan baris pertama
#!
jika Anda mengharapkannya hanya komentar biasa dan bukan omong kosong), tetapi bahwa POSIX tidak memberi Anda jaminan jika Anda melakukannya.Dalam pengalaman saya, menggunakan shebang memberi Anda lebih banyak jaminan portabilitas daripada menggunakan cara POSIX untuk menulis skrip shell: tinggalkan she-bang, tulis skrip dalam
sh
sintaks POSIX dan berharap bahwa apa pun yang memanggil skrip memanggil POSIX compliantsh
di atasnya, yang merupakan boleh jika Anda tahu skrip akan dipanggil di lingkungan yang tepat oleh alat yang tepat tetapi tidak sebaliknya.Anda mungkin harus melakukan hal-hal seperti:
Jika Anda ingin portabel untuk Windows + Cygwin, Anda mungkin harus memberi nama file Anda dengan
.bat
atau.ps1
ekstensi dan menggunakan beberapa trik serupa untukcmd.exe
ataupowershell.exe
memanggil cygwinsh
pada file yang sama.sumber
sh
, skrip tersebut tidak memerlukan baris hashbang karena akan dijalankan oleh POSIXsh
.execlp
atauexecvp
digunakan, kan? Jika saya menggunakanexecve
, itu akan menghasilkan ENOEXEC?Anda tidak melihat cukup dalam.
Kembali pada 1980-an, mekanisme ini tidak standar de facto. Meskipun Dennis Ritchie telah mengimplementasikannya, implementasi itu belum mencapai publik di sisi AT&T alam semesta. Secara efektif hanya tersedia untuk umum dan dikenal di BSD; dengan skrip shell yang dapat dieksekusi tidak tersedia di AT&T Unix. Jadi tidak masuk akal untuk membakukannya. Keadaan hubungan dicontohkan oleh dokumen kontemporer ini, salah satu dari banyak seperti:
- Stephen Frede (1988). "Pemrograman pada Sistem X Rilis Y". Newsletter Kelompok Pengguna Australian Unix Systems . Volume 9. Nomor 4. p. 111.Poin penting di sini adalah bahwa Anda melihat shell, sedangkan keberadaan skrip shell yang dapat dieksekusi sebenarnya adalah masalah
exec…()
fungsi. Apa yang dilakukan oleh shell termasuk prekursor dari mekanisme skrip yang dapat dieksekusi, masih dapat ditemukan di beberapa shell bahkan hari ini (dan juga saat ini diamanatkan untukexec…p()
subset fungsi), dan agak menyesatkan. Apa yang perlu diperhatikan oleh standar dalam hal ini adalah bagaimanaexec…()
pada skrip yang diinterpretasikan bekerja, dan pada saat POSIX awalnya dibuat, ia sama sekali tidak bekerja di tempat pertama di seluruh bagian utama dari spektrum sistem operasi target .Pertanyaan bawahan adalah mengapa hal ini belum distandarisasi sejak saat itu, terutama karena mekanisme angka ajaib untuk penerjemah skrip telah mencapai publik di sisi AT&T alam semesta dan telah didokumentasikan
-exec…()
dalam System 5 Interface Definition , pada pergantian tahun 1990-an. :exec
. Sistem V Interface Definition . Volume 1. 1991.Sayangnya, tingkah laku ini masih berbeda hingga hampir sama dengan tahun 1980-an dan tidak ada perilaku yang benar-benar umum untuk dibakukan. Beberapa Unices (misalnya HP-UX dan FreeBSD, misalnya) tidak mendukung skrip sebagai penerjemah skrip. Apakah baris pertama adalah satu, dua, atau banyak elemen yang dipisahkan oleh spasi putih bervariasi antara MacOS (dan versi FreeBSD sebelum 2005) dan lainnya. Panjang jalur maksimum yang didukung bervariasi.
␀
dan karakter melebihi set karakter nama file portabel POSIX yang rumit, seperti halnya memimpin dan mengikuti spasi putih. Apa argumen 0, 1, dan 2 akhirnya juga rumit, dengan variasi yang signifikan di seluruh sistem. Beberapa saat ini POSIX-conformant tetapi nonSistem -Unix masih tidak mendukung mekanisme seperti itu, dan mengamanatkan itu akan mengubahnya menjadi tidak lagi sesuai POSIX.Bacaan lebih lanjut
script
. Manual Informasi Miscellaneous NetBSD . 2005-05-06.sumber
Sebagaimana dicatat oleh beberapa jawaban lain, implementasi bervariasi. Ini membuat sulit untuk menstandarisasi dan mempertahankan kompatibilitas ke belakang dengan skrip yang ada. Ini berlaku bahkan untuk sistem POSIX modern. Sebagai contoh, Linux tidak sepenuhnya tokenize garis shebang oleh spasi. macOS tidak mengizinkan penerjemah skrip menjadi skrip lain.
Lihat juga http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability
sumber