雙銳總是抵消shebang嗎?
額外的
#
總能抵消尖銳的感嘆嗎?如:啟用:
#!/foo/bar
殘疾人:
##!/foo/bar
是否有任何已知的情況可以讓 exec 執行
bar
?有沒有\x23\x23\x21...
公認的魔法的環境?
好吧,無論哪種方式, POSIX 標準都無話可說:
一種常見的歷史實現是 execl()、execv()、execle() 和 execve() 函式返回一個
$$ ENOEXEC $$任何無法辨識為執行檔的錯誤,包括 shell 腳本。當 execlp() 和 execvp() 函式遇到這樣的文件時,它們假定該文件是一個 shell 腳本並呼叫已知的命令解釋器來解釋這些文件。這現在是 POSIX.1-2008 所要求的。execvp() 和 execlp() 的這些實現只給出$$ ENOEXEC $$在命令解釋器的執行檔出現問題的罕見情況下出現錯誤。由於這些實現,$$ ENOEXEC $$execlp() 或 execvp() 沒有提到錯誤,儘管實現仍然可以給出它。 一些歷史實現處理 shell 腳本的另一種方法是將文件的前兩個字節辨識為字元串“#!”。並使用文件第一行的其餘部分作為要執行的命令解釋器的名稱。
標准開發人員指出的一個潛在混淆來源是程序映像文件的內容如何影響 exec 系列函式的行為。以下是所採取行動的說明:
- 如果程序映像文件是該系統的有效執行檔(以可執行且有效且具有適當特權的格式),則係統執行該文件。
- 如果程序映像文件具有適當的權限並且是可執行但對該系統無效的格式(例如對於另一個體系結構的可辨識二進製文件),那麼這是一個錯誤並且 errno 設置為
$$ EINVAL $$(見後面的基本原理$$ EINVAL $$). 3. 如果程序映像文件具有適當的權限但未被辨識:
1. 如果這是對 execlp() 或 execvp() 的呼叫,那麼它們會呼叫命令解釋器,假設程序映像文件是 shell 腳本。 2. 如果這不是對 execlp() 或 execvp() 的呼叫,則會發生錯誤並將 errno 設置為
$$ ENOEXEC $$.
您會注意到它沒有指定如何辨識 3.1 中的命令解釋器。
但是在Linux上,要求 shebang 完全以開頭
#!
。見man 2 execve
:execve() executes the program pointed to by filename. filename must be either a binary executable, or a script starting with a line of the form: #! interpreter [optional-arg]
並且
#
是一個足夠常見的評論字元,這就是為什麼##!
似乎在沒有任何其他效果的情況下取消了 shebang。但是,腳本仍然會使用 執行sh
,因此即使/foo/bar
沒有執行,也可能不是您所期望的。見man 3 exec
:If the header of a file isn't recognized (the attempted execve(2) failed with the error ENOEXEC), these functions will execute the shell (/bin/sh) with the path of the file as its first argument. (If this attempt fails, no further searching is done.)
我不知道有任何系統接受除了 之外的 shebangs
#!
,當然我懷疑是否##!
會受到特殊對待,但這當然是可能的——標準並不排除它。