2011-10-19 20 views
7

我意外地用$!而不是#!啓動了一個bash腳本,並且出現了一些非常奇怪的行爲。我試圖弄清楚發生了什麼事。

如果你試試這個腳本:

$!/bin/bash 
echo Hello world! 

您將獲得以下行爲:

$ chmod +x hello 
$ ./hello 
[nothing happens, get prompt back] 
$ exit 
exit 
Hello world! 
$ 

所以它看起來像這樣發生了:

  1. 一個新的bash shell產生。
  2. 退出後,執行腳本的其餘部分。

這是怎麼回事?發生什麼事情?如果沒有#!,shell如何知道使用bash來解釋腳本?

顯然這是「滿足我的好奇心」而不是「解決我的問題」的問題。谷歌搜索不會產生太多,可能是因爲#!$!查詢不會讓谷歌機器人快樂。

回答

9

$東西是一個參數( 「變量」)擴張,但在特定的回報是不是在你的腳本中設置的值$!,所以它會擴展爲零長度的字符串。

因此你的腳本,你是正確的,相當於:

/bin/bash 
echo Hello world! 

shebang magic number是Unix的一個老功能,但外殼是更老。執行位設置爲內核不能執行的文本文件(因爲它沒有實際編譯)由子shell執行。也就是說,shell故意運行另一個shell並將路徑名作爲參數傳遞。這就是在shebang被髮明之前如何執行以shell腳本編寫的命令,並且它仍然存在於代碼中。

3

@DigitalRoss的回答擴大了一點。

第一行沒有#!的可執行腳本由/bin/sh執行 - 即使您從bash(或tcsh)執行它。這不是shell功能,它在內核中。

因此,當你執行你的腳本,它是由/bin/sh執行(這意味着,在大多數系統上,這將無法使用bash的特定的功能),$!擴大到什麼(因爲shell有沒有啓動任何後臺進程),並且第一行調用一個交互式/bin/bash shell。然後退出該交互式shell,腳本執行echo Hello world!行並終止,將您重置回原始shell。例如,如果您將echo Hello world!更改爲echo $BASH_VERSION,則會發現它不會打印任何內容 - 如果您從被調用的交互式bash外殼中鍵入history,則它不會顯示任何內容。