天天看點

linux不能用bash,在Linux和BSD中使用和不使用shebang的Bash腳本執行

當類似Bash的腳本以二進制形式執行而沒有shebang時,如何确定由誰執行?

我猜想 使用 shebang

運作普通腳本是由binfmt_script

Linux子產品處理的,該子產品檢查shebang,解析指令行并運作指定的腳本解釋器。

但是,如果有人在沒有腳本的情況下運作腳本會發生什麼?我已經測試了直接execv方法,發現裡面沒有核心魔術,即像這樣的檔案:

$ cat target-script

echo Hello

echo "bash: $BASH_VERSION"

echo "zsh: $ZSH_VERSION"

運作僅執行execv調用的已編譯C程式将産生:

$ cat test-runner.c

void main(){

如果(execv(“ ./ target-script”,0)== -1)

perror();

}

$ ./測試運作器

./target-script:執行格式錯誤

但是,如果我從另一個shell腳本執行相同的操作,它将使用與原始腳本相同的shell解釋器運作目标腳本:

$ cat test-runner.bash

#!/ bin / bash

./target-script

$ ./test-runner.bash

你好

bash:4.1.0(1)-釋出

zsh:

如果我對其他外殼(例如,Debian的預設設定sh- /bin/dash)執行相同的操作,那麼它也可以工作:

$ cat test-runner.dash

#!/ bin /破折号

./target-script

$ ./test-runner.dash

你好

重擊:

zsh:

奇怪的是,它與zsh的配合使用效果不佳,也沒有遵循一般的方案。看起來zsh /bin/sh畢竟對這樣的檔案執行了:

greycat @ burrow-debian〜/ z / test-runner $ cat test-runner.zsh

#!/ bin / zsh

回聲ZSH_VERSION = $ ZSH_VERSION

./target-script

greycat @ burrow-debian〜/ z / test-runner $ ./test-runner.zsh

ZSH_VERSION = 4.3.10

你好

重擊:

zsh:

請注意,ZSH_VERSION在父腳本中有效,而ZSH_VERSION在子腳本中則無效!

如果沒有shebang,shell(Bash,破折号)如何确定執行什麼操作?我試圖在Bash /

dash來源中挖掘該位置,但是,a,我似乎迷失了。任何人都可以闡明一種神奇的方法,這種方法确定應将沒有shebang的目标檔案作為腳本執行還是作為Bash

/ dash中的二進制檔案執行?或者可能存在 的 某種互動的核心/ libc和那麼我會在它是如何在Linux和FreeBSD核心/

libcs工作歡迎解釋嗎?