Skrip Anda mungkin memiliki ujung garis CR-LF gaya DOS dan bukan ujung garis LF gaya Unix. ^ M yang terlihat dalam pesan kesalahan dalam kasus pertama adalah indikasi bahwa karakter 0D ditafsirkan sebagai bagian dari nama juru bahasa skrip dan bukan sebagai bagian dari akhir baris (seperti yang diharapkan). Karena tidak ada file yang dapat dieksekusi pada sistem Anda dengan lintasan yang menyertakan karakter 0D (^ M), sistem tidak dapat memanggil penerjemah. Saat Anda memanggil juru bahasa Anda secara manual, ia mampu menangani kedua jenis akhiran baris yang ada dalam skrip.
Jika Anda mengonversi skrip untuk menggunakan ujung garis LF gaya Unix, Anda akan melihat shebang berfungsi. Baca terus untuk ilustrasi.
Dalam sesi di bawah ini, todos dan fromdos adalah utilitas (tersedia di Ubuntu sebagai paket tofrodos
) untuk mengubah konvensi akhir baris dari CR-LF ke LF. Utilitas yang setara (lihat pertanyaan unix.SE ini ) akan dilakukan untuk tujuan demonstrasi.
Transkrip sesi berikut (dijalankan dengan file skrip yang sama) harus menjelaskan situasi:
$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$
Ini tampaknya bahwa itu adalah kernel yang membaca garis peristiwa, dan tampaknya kernel Linux (setidaknya dari versi pada sistem Saucy Kubuntu saya) tidak mengakui CR sebagai bagian dari garis CR-LF berakhir konvensi.
Jika shebang skrip Anda tampaknya tidak berfungsi (yaitu memanggil penerjemah secara manual pada skrip berfungsi tetapi Anda tidak dapat menjalankan skrip menggunakan nama file-nya meskipun Anda telah melakukannya chmod +x
) maka ini adalah kemungkinan alasan.
CATATAN:
Terima kasih kepada yang lain yang berkomentar juga. Saya juga akan senang mendengar jika ada jawaban yang lebih baik!