本頁使用了標題或全文手工轉換

Shebang

維基百科,自由的百科全書
前往: 導覽搜尋

電腦科學中,Shebang(也稱為 Hashbang )是一個由井號驚嘆號構成的字元序列 #! ,其出現在文字檔案的第一行的前兩個字元。 在檔案中存在 Shebang 的情況下,類 Unix 作業系統程式載入器會分析 Shebang 後的內容,將這些內容作為直譯器指令,並呼叫該指令,並將載有 Shebang 的檔案路徑作為該直譯器的參數[1]

例如,以指令

#!/bin/sh

開頭的檔案在執行時會實際呼叫 /bin/sh 程式(通常是 Bourne shell 或相容的 shell,例如 bashdash 等)來執行。這行內容也是 shell 指令碼的標準起始行。

由於 # 符號在許多手稿語言中都是注釋識別元,Shebang 的內容會被這些指令碼直譯器自動忽略。 在 # 字元不是注釋識別元的語言中,例如 Scheme,直譯器也可能忽略以 #! 開頭的首行內容,以提供與 Shebang 的相容性[2]

"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 呼叫之。[3]

在2010年版的 Advanced bash scripting guide(revision 6.2)中,shebang 被稱為 "sha-bang",同時提到"也寫作 she-bang 或 sh-bang",但該檔案中沒有提到 "shebang" 這一形式。

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

發信人:"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行,例如對於下面的指令碼,

#!/bin/cat
Hello world!

cat 會把檔案中的兩行都輸出到標準輸出中。

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

Linux的作業系統的檔案一般是UTF-8編碼。如果指令碼檔案是以 UTF-8 的 BOM(0xEF 0xBB 0xBF) 開頭的,那麼 exec 函式將不會啟動 shebang 指定的直譯器來執行該指令碼。因此,Linux 的指令碼檔案不應在檔案開頭包含 UTF-8 的 BOM

參見[編輯]

參考文獻[編輯]

  1. ^ execve(2) - Linux man page. [2010-10-21]. 
  2. ^ Martin Gasbichler and Michael Sperber. SRFI 22: Running Scheme Scripts on Unix. [2011-03-19]. 
  3. ^ Jargon File entry for shebang. Catb.org. [2010-06-16]. 

外部連結[編輯]