Linux腳本第一行的祕密:#!/usr/bin/env bash#!/bin/bash 其實是什麼?

在 Linux 上撰寫腳本時,我們習慣在最上面寫下這行。

#!/usr/bin/env bash

#!/bin/bash

表面上看起來像是註解…這一行到底是什麼?兩者又有什麼差別?本文將帶你正確理解這一行,並說明何時該使用哪種方式。


1. 這不是註解:shebang(#!)是什麼?



#! 開頭的這一行稱為 shebang(#!)

#!/bin/bash

從 shell 的角度看,因為以 # 開頭,會被視為「註解」。 但從 作業系統(核心) 的角度來說,這不是註解,而是:

「告訴系統這個腳本要用哪個解譯器執行」

也就是說,

  • #!/bin/bash → 「請用 /bin/bash 執行這個檔案」
  • #!/usr/bin/env bash → 「請透過 env 找到 bash 解譯器,並用它執行這個檔案」

2. 核心如何執行腳本?

執行流程簡化如下:

  1. 使用者執行有執行權限的腳本
chmod +x script.sh
./script.sh
  1. 核心讀取 script.sh
  2. 檢查檔案前兩個字元是否為 #!
  3. 若是,將該行剩餘部分視為 * 「解譯器路徑 + 參數」 * 並以此程式執行,同時把腳本檔案路徑作為參數傳遞

例如 script.sh 的第一行是:

#!/bin/bash

核心實際執行的相當於:

/bin/bash script.sh

也就是說,核心替我們執行了 bash script.sh

注意: #!/ 前不能有空白。 檔案第一個字元必須是 #,第二個是 !


3. #!/bin/bash 的意義與特點



最常見的寫法就是這個。

#!/bin/bash

意義

  • 「這個腳本是 bash 腳本,bash 位於 /bin/bash
  • 核心執行時會固定使用 /bin/bash

優點

  • 明確:永遠使用 /bin/bash,可預測使用的是哪個 bash。
  • 效能/簡單:不經過 env,直接執行,省去路徑搜尋。
  • 大多數 Linux 發行版將 /bin/bash 視為「標準位置」。

缺點

  • 可攜性差
  • 某些系統 bash 可能位於 /usr/bin/bash/usr/local/bin/bash 等。
  • 有些系統甚至沒有 bash,只安裝了 /bin/sh
  • 在 macOS、BSD、NixOS、部分容器環境等,路徑可能不同。

4. #!/usr/bin/env bash 的意義與特點

近年來腳本中常見的寫法。

#!/usr/bin/env bash

核心關鍵是 /usr/bin/env

  • env 是「環境變數設定/檢查 + 依 PATH 搜尋程式」的工具。
  • 核心實際執行相當於: bash /usr/bin/env bash script.sh
  • env 會查看系統的 PATH,在其中尋找 bash 執行檔。

優點

  1. 可攜性好: * 無論 bash 位於 /bin/bash/usr/bin/bash/usr/local/bin/bash,只要在 PATH 中,env 都能找到。
  2. 符合使用者環境: * 若使用者在 PATH 中自訂了特定版本的 bash,腳本會自動使用該版本。
  3. Python 等語言也可類似使用 python #!/usr/bin/env python3

缺點

  1. 必須存在 /usr/bin/env: * 大多數現代 Unix/Linux 系統都有,但極少數特殊環境可能沒有。
  2. PATH 影響: * PATH 設定不當或有意外的 bash 在前,可能執行錯誤版本。
  3. 安全性考量: * 在高度安全敏感環境,依賴 PATH 可能不被允許,偏好使用絕對路徑。

5. 兩種方式比較

簡易表格整理:

分類 #!/bin/bash #!/usr/bin/env bash
解譯器定位方式 絕對路徑固定 透過 PATH 搜尋
可攜性 低(路徑不同會失效) 高(只要在 PATH
使用的 bash 永遠 /bin/bash PATH 中第一個找到的 bash
版本保證 相對容易 取決於 PATH
安全/控制 更強(路徑固定) 稍弱(依 PATH
近期趨勢 舊風格 趨勢較新、被推薦

6. 何時使用哪種?

「結論上我該用哪個?」的情境整理:

1) 個人或團隊開發腳本(一般開發環境)

建議使用:

#!/usr/bin/env bash

原因:

  • 開發者可能在本機、CI、不同伺服器上,bash 位置不一。
  • PATH 方式更靈活,符合現代工具習慣。

2) 特定伺服器環境的運維腳本

若公司所有伺服器都安裝在 /bin/bash,且環境固定:

#!/bin/bash

原因:

  • 保證使用同一個解譯器,避免 PATH 變動帶來的意外。

3) 想要最大可攜性?

若擔心某些環境根本沒有 bash,先考慮是否真的需要 bash。

  • 可改用 shbash #!/bin/sh
  • 但要避免使用 bash 專屬語法([[ ]]、陣列、擴展字串處理等)。

7. 使用 #!/usr/bin/env bash 的實戰技巧

1) 正確執行腳本

為了讓 shebang 發揮作用,請避免直接用 bash script.sh 執行,改用:

chmod +x script.sh   # 給予執行權限
./script.sh          # 直接執行

這樣核心會讀取 #!,並以指定的解譯器執行。

2) 確認參數傳遞

範例 test.sh

#!/usr/bin/env bash

echo "Interpreter: $0"
echo "Arguments: $@"

執行:

chmod +x test.sh
./test.sh hello world

輸出:

Interpreter: ./test.sh
Arguments: hello world

這裡 $0 是腳本自身路徑,核心實際執行的是 /usr/bin/env bash test.sh hello world


8. 常見誤解

「第一行只是註解,沒必要寫」

  • 事實上,不是必須
  • 若直接指定解譯器執行(bash myscript.shpython3 myscript.py),shebang 被忽略。
  • 但若想用 ./myscript.sh./myscript.py 直接執行,shebang 必須

#!/usr/bin/env 之外還能寫 #!/bin/env

  • 有些系統確實有 /bin/env
  • /usr/bin/env 是更通用、標準的位置,除非有特殊需求,建議使用 /usr/bin/env

9. 小結

  • #!/usr/bin/env bash#!/bin/bash 都不是註解,而是告訴核心「用哪個解譯器執行」的指令。
  • #!/bin/bash:固定使用 /bin/bash,環境可預測但可攜性差。
  • #!/usr/bin/env bash:透過 PATH 搜尋 bash,較為靈活、可攜,但受 PATH 影響。
  • 在一般開發/部署環境,建議採用 #!/usr/bin/env bash;若環境固定且想確保一致性,可選 #!/bin/bash

image of shebang in linux script