#!
は"シェバング"と読むらしい。
スクリプトの最初に示すことで、実行するインタプリタを指定できる。
例えば次の場合を考える。
#!/usr/bin/fish echo "hello"
これをfishから実行する。
./test.sh
このとき、次の流れが行われる。
せっかくなのでstraceでOSの動きを眺める。
strace ./test.sh 2>&1 | grep "read" | grep "fish" readlink("/proc/self/exe", "/usr/bin/fish", 4095) = 13 readlink("/usr/bin/fish", 0x7ffc244bb390, 1023) = -1 EINVAL (Invalid argument) read(4, "# This file contains fish univer"..., 4096) = 1624 read(4, "# Main file for fish command com"..., 4096) = 4096 read(12, "pported by fish\n set -ug FIG_CH"..., 128) = 128 read(12, "lor=%s\" \"$fish_color_autosuggest"..., 128) = 128 read(12, "g_copy_fn fish_mode_prompt fig_u"..., 128) = 128 read(12, " function fish_right_prompt"..., 128) = 128 read(4, "# Put system-wide fish configura"..., 4096) = 425 read(4, "#!/usr/bin/fish\necho \"hello\"\n", 4096) = 29
2>&1
で繋いでいるのは、straceで得られるあれこれは標準エラーに出るらしいからである。/usr/bin/fish
であれこれしていそうな様子は分かるが、シェバングを読んでいる感じではなさそう?もう少しシンプルな内容で実験してみる。
#!hoge echo "hello"
存在しないインタプリタを指定した。
strace ./test.sh execve("./test.sh", ["./test.sh"], 0x7ffcc2c81000 /* 41 vars */) = -1 ENOENT (No such file or directory) strace: exec: No such file or directory +++ exited with 1 +++
hoge
に関するログは出ない。
どうやら、シェバングの処理はシステムコールのトレースでは拾えないところで作業しているらしい。おそらくexecveの前段階。