The exec
system call dari kernel Linux mengerti shebangs ( #!
) native
Ketika Anda melakukannya di bash:
./something
di Linux, ini memanggil exec
system call dengan path ./something
.
Baris kernel ini dipanggil pada file yang diteruskan ke exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
Itu membaca byte pertama file, dan membandingkannya #!
.
Jika perbandingannya benar, maka seluruh baris diuraikan oleh kernel Linux, yang membuat exec
panggilan lain dengan path /usr/bin/env python
dan file saat ini sebagai argumen pertama:
/usr/bin/env python /path/to/script.py
dan ini berfungsi untuk bahasa skrip apa pun yang digunakan #
sebagai karakter komentar.
Dan ya, Anda dapat membuat loop tanpa batas dengan:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
Bash mengenali kesalahan:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#!
Kebetulan bisa dibaca manusia, tapi itu tidak wajib.
Jika file dimulai dengan byte yang berbeda, maka exec
panggilan sistem akan menggunakan penangan yang berbeda. Handler internal terpenting lainnya adalah file yang dapat dieksekusi ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 yang memeriksa byte 7f 45 4c 46
(yang juga merupakan manusia dapat dibaca untuk .ELF
). Mari kita konfirmasi dengan membaca 4 byte pertama /bin/ls
, yang merupakan executable ELF:
head -c 4 "$(which ls)" | hd
keluaran:
00000000 7f 45 4c 46 |.ELF|
00000004
Jadi ketika kernel melihat byte-byte itu, ia mengambil file ELF, memasukkannya ke dalam memori dengan benar, dan memulai proses baru dengannya. Lihat juga: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Akhirnya, Anda dapat menambahkan penangan shebang Anda sendiri dengan binfmt_misc
mekanismenya. Misalnya, Anda dapat menambahkan penangan khusus untuk .jar
file . Mekanisme ini bahkan mendukung penangan melalui ekstensi file. Aplikasi lain adalah untuk menjalankan executable dari arsitektur yang berbeda dengan QEMU .
Saya tidak berpikir POSIX menentukan shebangs, namun: https://unix.stackexchange.com/a/346214/32558 , meskipun ia menyebutkannya di bagian rasional, dan dalam bentuk "jika skrip yang dapat dieksekusi didukung oleh sistem sesuatu mungkin terjadi ".
chmod +x my_shell_script.sh ; /path/to/my_shell_script.sh # or ./my_shell_script.sh if you happen to be in its directory