Shebang

类Unix脚本的开头的“#!”符号

計算領域中,Shebang(也稱為Hashbang)是一個由井號嘆號構成的字符序列#!,其出現在文本文件的第一行的前兩個字符。 在文件中存在Shebang的情況下,類Unix操作系統程序載入器會分析Shebang後的內容,將這些內容作為解釋器指令,並調用該指令,並將載有Shebang的文件路徑作為該解釋器的參數[1][2]

例如,以指令#!/bin/sh開頭的文件在執行時會實際調用/bin/sh程序(通常是Bourne shell或兼容的shell,例如bashdash等)來執行。這行內容也是shell腳本的標準起始行。

由於#符號在許多腳本語言中都是注釋標識符,Shebang的內容會被這些腳本解釋器自動忽略。 在#字符不是注釋標識符的語言中,例如Scheme,解釋器也可能忽略以#!開頭的首行內容,以提供與Shebang的兼容性[3]

"Shebang"或者說"Hashbang"的名字有時也被當做Ajax應用程序中的分段標識符,用於瀏覽器的狀態保存;Google網站站長中心提到,以嘆號開頭的分段標識符(即...url#!state...)會為Google的網頁爬蟲所索引。

語法

Shebang這一語法特性由#!開頭,即井號嘆號。 在開頭字符之後,可以有一個或數個空白字符,後接解釋器的絕對路徑,用於調用解釋器。 在直接調用腳本時,調用者會利用Shebang提供的信息調用相應的解釋器,從而使得腳本文件的調用方式與普通的可執行文件類似。

詞源與歷史

Shebang的名字來自於SHArpbang,或haSH bang縮寫,指代Shebang中#!兩個符號的典型Unix名稱。 Unix術語中,井號通常稱為sharphashmesh;而嘆號則常常稱為bang。也有看法認為,shebang名字中的sh來自於默認shell————Bourne shell的名稱,sh,因為常常使用shebang調用之。[4][1]

在2010年版的Advanced bash scripting guide頁面存檔備份,存於網際網路檔案館)(revision 6.2)中,shebang被稱為"sha-bang",同時提到"也寫作she-bang或sh-bang",但該文件中沒有提到"shebang"這一形式。[1]

丹尼斯·里奇在被問及他會如何稱呼這一特性時,他答道:

發信人:"Ritchie, Dennis M (Dennis)** CTR **" <dmr@[redacted]>

收信人:<[redacted]@talisman.org>

日期:Thu, 19 Nov 2009 18:37:37 -0600

主題:RE: What do -you- call your #!<something> line?

我不記得我們曾經給它取過一個適當的名字。導入這一特性已經是相當晚了--我覺得我是從關於伯克利Unix的UCB會議上的某人那裡得到的這一靈感;我可能是首先實現它的人之一,但這個創意是來自於別人的。

至於它的名字:可能是類似於"hash-bang"的英國風描述性文字,但我沒有在任何場合使用類似寵物的名字來描述它。

此致,

Dennis

例子

下面列出了一些典型的 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的命令行解釋器執行

在許多系統上,/bin/sh軟鏈接硬鏈接Bash,而/bin/csh則鏈接到tcsh,因此設定前面的解釋器實際上是運行的與之兼容的,或改進的版本。

Shebang行也可以包含需要傳遞到解釋器的特定選項(見下文的Perl例子)。然而,選項傳遞的方式隨實現的不同而不同。

用途

解釋器指令允許腳本和數據文件充當系統命令,無需在調用時由用戶指定解釋器,從而對用戶和其它程序隱藏其實現細節。

假設/usr/local/bin/foo中有一以下行開頭的Bourne shell腳本 #!/bin/sh -x 而它被如此調用("$"是命令提示符) $ foo bar 該命令的輸出等同於 $ /bin/sh -x /usr/local/bin/foo bar 除了argv[0]被設定為腳本的文件名,而非解釋器的文件名外。

由於sh從其命令行指定的文件中讀取命令,上面的命令就會執行/usr/local/bin/foo中的命令,同時,將bar作為foo命令的參數$1

由於shebang開頭的井號也是Bourne shell和許多其它解釋性語言的注釋符,因此在這些語言中,解釋器指令本身會被解釋器認為是單純的注釋而跳過。 然而,並不是每一種解釋器都會自動忽略shebang行,例如對於下面的腳本,cat會把文件中的兩行都輸出到標準輸出中。

#!/bin/cat
Hello world!

使用#!/usr/bin/env 脚本解释器名称是一種常見的在不同平台上都能正確找到解釋器的辦法。

Linux的操作系統的文件一般是UTF-8編碼。如果腳本文件是以UTF-8的BOM(0xEF 0xBB 0xBF)開頭的,那麼exec函數將不會啟動shebang指定的解釋器來執行該腳本。因此,Linux的腳本文件不應在文件開頭包含UTF-8的BOM

參見

參考文獻

  1. ^ 1.0 1.1 1.2 Advanced Bash Scripting Guide: Chapter 2. Starting Off With a Sha-Bang. [2019-12-10]. (原始內容存檔於2019-12-10). 
  2. ^ execve(2) - Linux man page. [2010-10-21]. (原始內容存檔於2010-11-02). 
  3. ^ Martin Gasbichler and Michael Sperber. SRFI 22: Running Scheme Scripts on Unix. [2011-03-19]. (原始內容存檔於2011-02-27). 
  4. ^ Jargon File entry for shebang. Catb.org. [2010-06-16]. (原始內容存檔於2011-06-04). 

外部連結