使用類Unix系統的同學可能都對“ !”這個符號並不陌生,但是你真的瞭解它嗎? 這個符號的名稱,叫做”Shebang”或者”Sha bang”。長期以來,Shebang都沒有正式的中文名稱。Linux中國翻譯組的GOLinux將其翻譯為“釋伴”,即“解釋伴隨行”的簡稱,同時又是Shebang的音譯。 ...
使用類Unix系統的同學可能都對“#!”這個符號並不陌生,但是你真的瞭解它嗎?
這個符號的名稱,叫做”Shebang”或者”Sha-bang”。長期以來,Shebang都沒有正式的中文名稱。Linux中國翻譯組的GOLinux將其翻譯為“釋伴”,即“解釋伴隨行”的簡稱,同時又是Shebang的音譯。本文將簡單介紹一下Shebang這個符號。
用法
Shebang通常出現在類Unix系統的腳本中第一行,作為前兩個字元。在Shebang之後,可以有一個或數個空白字元,後接解釋器的絕對路徑,用於指明執行這個腳本文件的解釋器。在直接調用腳本時,系統的程式載入器會分析 Shebang 後的內容,將這些內容作為解釋器指令,並調用該指令,將載有 Shebang 的文件路徑作為該解釋器的參數,執行腳本,從而使得腳本文件的調用方式與普通的可執行文件類似。例如,以指令#!/bin/sh開頭的文件,在執行時會實際調用 /bin/sh 程式(通常是 Bourne shell 或相容的 shell,例如 bash、dash 等)來執行。
由於 # 符號在許多腳本語言中都是註釋標識符,Shebang 的內容會被這些腳本解釋器自動忽略。 在 # 字元不是註釋標識符的語言中,例如 Scheme,解釋器也可能忽略以 #! 開頭的首行內容,以提供與 Shebang 的相容性。
Shebang的一些具體用法羅列如下:
1、如果腳本文件中沒有#!這一行,那麼執行時會預設採用當前Shell去解釋這個腳本(即:$SHELL環境變數)。
2、如果#!之後的解釋程式是一個可執行文件,那麼執行這個腳本時,它就會把文件名及其參數一起作為參數傳給那個解釋程式去執行。
3、如果#!指定的解釋程式沒有可執行許可權,則會報錯“bad interpreter: Permission
denied”。如果#!指定的解釋程式不是一個可執行文件,那麼指定的解釋程式會被忽略,轉而交給當前的SHELL去執行這個腳本。
4、如果#!指定的解釋程式不存在,那麼會報錯“bad interpreter: No such file or directory”。註意:#!之後的解釋程式,需要寫其絕對路徑(如:#!/bin/bash),它是不會自動到$PATH中尋找解釋器的。
5、當然,如果你使用類似於”bash test.sh”這樣的命令來執行腳本,那麼#!這一行將會被忽略掉,解釋器當然是用命令行中顯式指定的bash。
6、腳本文件必須擁有可執行許可權。
Shebang的好處在於,允許腳本和數據文件充當系統命令,無需在調用時由用戶指定解釋器,從而對用戶和其它程式隱藏其實現細節。下麵我們一起來看幾個典型的例子:
#!/bin/sh:使用 sh,即 Bourne shell 或其它相容 shell 執行腳本
#!/bin/csh:使用 csh,即 C shell 執行
#!/usr/bin/perl -w:使用帶警告的 Perl 執行
#!/usr/bin/python -O:使用具有代碼優化的 Python 執行
#!/usr/bin/php:使用 PHP 的命令行解釋器執行
Shebang 行也可以包含需要傳遞到解釋器的特定選項(如上述的 Perl 和 Python 例子)。
這裡有兩點需要註意的地方:
(1).之前我們提到過,解釋器指令本身會被解釋器認為是單純的註釋而跳過。 然而,並不是每一種解釋器都會自動忽略Shebang行,例如對於下麵的腳本,
#!/bin/cat
Hello world!
cat 會把文件中的兩行都輸出到標準輸出中。
(2).使用 #!/usr/bin/env 腳本解釋器名稱 是一種常見的在不同平臺上都能正確找到解釋器的辦法。因為env一般固定在/usr/bin目錄下,而其餘解釋器的安裝位置就相對不那麼固定。但是,用env時你應該註意這麼一個事實:傳遞給解釋器的argv和你想象得並不一樣。下麵這個就是不對的:
#!/usr/bin/env perl -w
shell會提示:/usr/bin/env: perl -w: No such file or directory。錯誤的根源就在於 perl -w 被當成了整體傳遞給env。
最後,我們來總結一下Shebang的幾點要求:
#! 必須連接在一起
#! 一句必須在文件的最開始,第一行
# 開頭的語句一般情況下會被當成註釋而忽略,所以Shebang 對文件的內容是沒有影響的
#! 開頭的一行會設置解釋器運行環境