哈嘍大家好,我是鹹魚 不知道小伙伴們在寫 Bash 腳本或者說看別人的 Bash 腳本的時候有沒有註意過腳本的第一行 #!/bin/bash Bash 腳本的第一行往往以 #! 開頭,這一行稱作 shebang 行 在 類 UNIX 系統中,shebang 行用來指定腳本的解釋器路徑,通常出現在第一 ...
哈嘍大家好,我是鹹魚
不知道小伙伴們在寫 Bash 腳本或者說看別人的 Bash 腳本的時候有沒有註意過腳本的第一行
#!/bin/bash
Bash 腳本的第一行往往以 #!
開頭,這一行稱作 shebang 行
在 類 UNIX 系統中,shebang 行用來指定腳本的解釋器路徑,通常出現在第一行,格式如下
#! interpreter_path
shebang 行中開頭 #!
字元的作用是告訴操作系統這不是一個普通二進位文件,而是需要通過解釋器運行的東西
而這個解釋器則通過 #!
字元後面來指定。例如 /bin/bash
表示使用 bash 解釋器來執行該腳本文件
下麵則是一些 Bash 腳本的 shebang 行,指定了不同的解釋器
#! /usr/bin/perl
#! /usr/bin/awk
#! /usr/bin/python
那麼這時候小伙伴們可能就會有疑問:我忘了加 shebang 行,腳本為什麼還能執行?
如果一個腳本沒有添加 shebang 行來指定解釋器路徑,則預設情況下系統會使用預設的 shell 來執行腳本,系統預設的 shell 可以通過下麵的命令來查看
# 一般情況下預設的 shell 為bash
echo $SHELL
現在我們知道了 shebang 行的作用,那麼我們現在來編寫一個腳本並修改 shebang 行試試
test.sh 內容如下:
#!/bin/bash
echo Hello
先給 test.sh 腳本添加一下執行許可權
chmod +x test.sh
接下來我們用幾種方式來執行這個腳本
可以看到腳本都成功執行了
下麵我們來改一下 shebang 行,將其改成其他命令
#!/usr/bin/ls -l
echo Hello
然後我們分別用幾種方式來執行這個腳本
上面腳本執行的結果是不是看的一臉懵逼,說實話我一開始看到的時候也是很懵
我們先來看下這四種腳本執行方式的區別
- bash tesh.sh
這種方式執行腳本的原理是將 test.sh 作為參數傳給 bash 解釋器(命令)來執行,而不是 test,sh 自己來執行
這種方式執行腳本不需要給腳本文件添加執行許可權、不需要寫 shebang 行指定解釋器路徑,因為腳本是作為參數被傳給 bash 來執行
- sh test.sh
這種執行腳本的方式跟上面的方式原理一樣,都是將腳本作為參數傳進去,只不過是這個方式用的是 sh 解釋器(命令),而不是 bash
- /root/test.sh
這種是通過絕對路徑去執行腳本,通過絕對路徑來執行腳本就需要腳本擁有執行許可權
當使用絕對路徑來執行腳本時,操作系統需要知道該腳本文件所使用的解釋器類型,這就需要依靠腳本文件中的 shebang 行
實際上你用絕對路徑執行腳本的時候,如果裡面定義了 shebang 行(例如 #! /bin/bash
)
那麼實際上跟下麵的命令是一樣的
/bin/bash /root/test.sh
在執行腳本的時候,操作系統會讀取腳本的 shebang 行
如果你的 shebang 行是其他 Linux 命令而不是解釋器,那麼就會導致操作系統將你的 shebang 行當作命令,而你的腳本則是命令的參數
就好比上面的例子,我將 shebang 行改成了 #! /usr/bin/ls -l
,當我執行腳本的時候其實就是下麵這樣的
/usr/bin/ls -l /root/test.sh
這樣會導致腳本無法執行
- ./test.sh
這種是通過相對路徑去執行腳本,跟上面用絕對路徑執行腳本方式是一樣的,只不過區別是一個是相對路徑一個是絕對路徑
總結:
- shebang 行通常出現在 UNIX 系統的腳本當中,用來指定腳本的解釋器路徑,出現在第一行,以
#!
開頭 - 如果腳本裡面沒有定義 shebang 行,系統會去找預設的解釋器,預設解釋器用
echo $SHELL
查看 - 用 bash 或者 sh 命令執行腳本的時候,其實是把腳本作為參數傳給 bash 或 sh 命令了,這時候腳本可以不添加執行許可權、可以不需要 shebang 行
- 如果用絕對路徑或者相對路徑的方式來執行腳本,需要腳本擁有執行許可權,如果 shebang 行定義的不是解釋器而是其他命令,就會導致腳本無法執行
附上參考鏈接:Shebang Shenanigans :: Linus Karlsson