Bash Shebang 與 Script 執行方式指南
Bash Shebang 與 Script 執行方式指南
Shebang 是 Shell Script 第一行的特殊宣告,用來告訴作業系統應該使用哪一個 Interpreter 執行這份檔案。
它最常用於:
- 指定 Script 使用 Bash、Python、Node.js 等程式執行
- 讓 Script 可以直接透過
./script.sh執行 - 避免 Script 被錯誤的 Shell 解讀
- 提高 Script 在不同環境中的可攜性
1. Shebang 是什麼?
Shebang 的基本格式是:
#!<interpreter 路徑>
例如 Bash Script 常見的寫法:
#!/usr/bin/env bash
其中:
| 部分 | 說明 |
|---|---|
#! |
Shebang 標記 |
/usr/bin/env |
從目前的 PATH 尋找程式 |
bash |
要使用的 Interpreter |
當執行:
./script.sh
作業系統會讀取 Script 第一行,並將檔案交給指定的 Interpreter。
例如:
#!/usr/bin/env bash
大致相當於:
/usr/bin/env bash ./script.sh
Shebang 必須位於檔案的第一行,前面不能有空白或空行。
2. Script 的三種執行方式
常見的執行方式有:
./script.sh
bash script.sh
sh script.sh
它們的差異如下:
| 執行方式 | 使用的 Interpreter | 使用 Shebang | 需要執行權限 |
|---|---|---|---|
./script.sh |
由 Shebang 決定 | 是 | 是 |
bash script.sh |
強制使用 Bash | 否 | 否 |
sh script.sh |
強制使用 sh |
否 | 否 |
3. 使用 ./script.sh
執行:
./script.sh
系統會根據 Script 第一行的 Shebang 選擇 Interpreter。
例如:
#!/usr/bin/env bash
代表使用 Bash 執行。
直接執行前,需要先設定執行權限:
chmod +x script.sh
接著執行:
./script.sh
如果沒有執行權限,可能會出現:
Permission denied
可以查看檔案權限:
ls -l script.sh
具有執行權限時,通常會看到:
-rwxr-xr-x
其中的 x 代表可執行。
4. 使用 bash script.sh
執行:
bash script.sh
代表直接要求 Bash 讀取並執行 Script。
這種方式:
-
不會根據 Shebang 選擇 Interpreter
-
不需要檔案具有執行權限
-
適合測試或明確指定 Bash
即使 Script 沒有 Shebang,仍然可以執行:
bash script.sh
但仍建議在正式 Script 中加入 Shebang,讓檔案的執行需求更清楚。
5. 使用 sh script.sh
執行:
sh script.sh
代表強制使用 sh 解讀 Script。
即使第一行寫著:
#!/usr/bin/env bash
Shebang 也會被忽略。
如果 Script 使用 Bash 專屬語法,可能會出現錯誤:
syntax error near unexpected token `<'
例如以下 Process Substitution 是 Bash 語法:
while read -r line; do
echo "$line"
done < <(printf '%s\n' one two three)
使用 Bash 執行:
bash script.sh
通常可以正常運作。
使用 sh 執行:
sh script.sh
則可能出現語法錯誤。
6. 常見 Bash 專屬語法
以下語法不保證能在一般 sh 中使用。
條件判斷
[[ -f "$file" ]]
POSIX sh 通常使用:
[ -f "$file" ]
Process Substitution
done < <(some_command)
Here String
read -r value <<< "$text"
ANSI-C Quoting
separator=
### 陣列
```bash
items=("one" "two" "three")
關聯式陣列
declare -A config
如果 Script 使用這些功能,應該明確使用 Bash:
#!/usr/bin/env bash
並使用以下方式執行:
./script.sh
或:
bash script.sh
7. 常見 Bash Shebang
使用 /bin/bash
#!/bin/bash
直接指定系統中的 /bin/bash。
優點:
-
Bash 路徑明確
-
不受使用者
PATH影響 -
適合固定的 Linux、Docker 或 CI 環境
缺點:
-
Bash 不一定存在於
/bin/bash -
在部分特殊系統中可攜性較低
使用 /usr/bin/env bash
#!/usr/bin/env bash
透過目前的 PATH 尋找 Bash。
優點:
-
跨環境可攜性較高
-
可以使用 Homebrew、Nix 等工具安裝的 Bash
-
適合開源專案與開發工具
缺點:
-
實際執行的 Bash 取決於
PATH -
不同使用者可能執行到不同版本的 Bash
一般跨平台 Script 常使用:
#!/usr/bin/env bash
使用 /usr/bin/bash
#!/usr/bin/bash
直接指定 /usr/bin/bash。
這個路徑不是所有作業系統都有,因此通常不適合作為跨平台 Script 的預設值。
可以使用以下指令查看 Bash 的實際位置:
command -v bash
可能輸出:
/bin/bash
或:
/opt/homebrew/bin/bash
8. /bin/bash 與 /usr/bin/env bash 的差異
| 項目 | #!/bin/bash |
#!/usr/bin/env bash |
|---|---|---|
| Bash 來源 | 固定 /bin/bash |
從 PATH 尋找 |
| 可攜性 | 較低 | 較高 |
| 執行版本 | 較固定 | 依環境而定 |
是否受 PATH 影響 |
否 | 是 |
| 適合情境 | 固定 Server、Container | 開發工具、跨平台專案 |
如果執行環境完全可控,可以使用:
#!/bin/bash
如果 Script 需要在不同 Linux、macOS 或開發環境中使用,可以考慮:
#!/usr/bin/env bash
9. macOS 的 Bash 版本
macOS 內建的 Bash 通常位於:
/bin/bash
但內建版本可能較舊。
使用 Homebrew 安裝新版 Bash:
brew install bash
Apple Silicon Mac 常見路徑:
/opt/homebrew/bin/bash
Intel Mac 常見路徑:
/usr/local/bin/bash
檢查目前 Bash 位置:
command -v bash
檢查 Bash 版本:
bash --version
如果使用:
#!/bin/bash
通常會執行 macOS 內建 Bash。
如果使用:
#!/usr/bin/env bash
則會執行 PATH 中最先找到的 Bash。
10. Shebang 與 Script 參數
不建議在 Shebang 中加入多個參數:
#!/usr/bin/env bash -e
部分系統可能會將:
bash -e
視為完整的程式名稱,而不是 bash 加上 -e 參數。
比較穩定的方式是將選項放在 Script 內容中:
#!/usr/bin/env bash
set -Eeuo pipefail
各選項的作用:
| 選項 | 說明 |
|---|---|
-e |
指令執行失敗時停止 |
-u |
使用未定義變數時報錯 |
-o pipefail |
Pipeline 中任一指令失敗即視為失敗 |
-E |
讓 ERR Trap 可以在函式等環境中繼承 |
11. 推薦的 Bash Script 開頭
跨平台開發工具可以使用:
#!/usr/bin/env bash
set -Eeuo pipefail
固定 Linux、Server 或 Container 環境可以使用:
#!/bin/bash
set -Eeuo pipefail
簡單的 Script 不一定需要啟用所有嚴格模式。
例如:
#!/usr/bin/env bash
set -e
echo "Starting script..."
應依照 Script 的錯誤處理需求選擇適合的設定。
12. 常見問題
為什麼 ./script.sh 可以,但 sh script.sh 不行?
因為:
./script.sh
會根據 Shebang 使用 Bash。
sh script.sh
則會忽略 Shebang,強制使用 sh。
如果 Script 包含 Bash 專屬語法,使用 sh 就可能失敗。
.sh 副檔名會決定使用哪個 Shell 嗎?
不會。
以下檔名都可以是 Bash Script:
script.sh
script
deploy
backup
真正決定 Interpreter 的是:
-
使用
./script時的 Shebang -
命令列明確指定的
bash或sh
為什麼 bash script.sh 不需要執行權限?
因為真正被執行的是 bash。
script.sh 只是 Bash 讀取的輸入檔案,因此只需要讀取權限。
為什麼 ./script.sh 需要執行權限?
因為作業系統會將 script.sh 視為可執行檔案,讀取其 Shebang 後再啟動對應的 Interpreter。
13. 語法檢查與除錯
在執行前檢查 Bash 語法:
bash -n script.sh
如果沒有輸出,通常代表沒有發現語法錯誤。
顯示實際執行的指令:
bash -x script.sh
也可以在 Script 中暫時加入:
set -x
停止顯示執行指令:
set +x
確認 Script 第一行:
head -n 1 script.sh
查看是否包含 Windows 換行字元:
file script.sh
如果 Script 使用 CRLF,Shebang 可能被解析成:
/usr/bin/env: ‘bash\r’: No such file or directory
可以轉換為 Unix 換行格式:
dos2unix script.sh
重點整理
- Shebang 是 Script 第一行的
#!宣告。 - Shebang 用來指定執行 Script 的 Interpreter。
./script.sh會根據 Shebang 執行。bash script.sh會強制使用 Bash。sh script.sh會強制使用sh並忽略 Shebang。.sh副檔名不會決定使用哪一個 Shell。- Bash Script 不應隨意使用
sh script.sh執行。 - 跨平台 Script 通常使用
#!/usr/bin/env bash。 - 固定 Linux 環境可以使用
#!/bin/bash。 - Script 執行選項建議寫在內容中,不要放在 Shebang。
- 可以使用
bash -n script.sh進行語法檢查。
延伸閱讀
- sh script.sh vs ./script.sh Execution Differences —
sh script.sh與./script.sh執行差異的精簡版整理。 - shell 快捷鍵指南 — 終端機日常操作快捷鍵。\t'
### 陣列
{{CODE_BLOCK_26}}
### 關聯式陣列
{{CODE_BLOCK_27}}
如果 Script 使用這些功能,應該明確使用 Bash:
{{CODE_BLOCK_28}}
並使用以下方式執行:
{{CODE_BLOCK_29}}
或:
{{CODE_BLOCK_30}}
---
## 7. 常見 Bash Shebang
### 使用 `/bin/bash`
{{CODE_BLOCK_31}}
直接指定系統中的 `/bin/bash`。
優點:
- Bash 路徑明確
- 不受使用者 `PATH` 影響
- 適合固定的 Linux、Docker 或 CI 環境
缺點:
- Bash 不一定存在於 `/bin/bash`
- 在部分特殊系統中可攜性較低
---
### 使用 `/usr/bin/env bash`
{{CODE_BLOCK_32}}
透過目前的 `PATH` 尋找 Bash。
優點:
- 跨環境可攜性較高
- 可以使用 Homebrew、Nix 等工具安裝的 Bash
- 適合開源專案與開發工具
缺點:
- 實際執行的 Bash 取決於 `PATH`
- 不同使用者可能執行到不同版本的 Bash
一般跨平台 Script 常使用:
{{CODE_BLOCK_33}}
---
### 使用 `/usr/bin/bash`
{{CODE_BLOCK_34}}
直接指定 `/usr/bin/bash`。
這個路徑不是所有作業系統都有,因此通常不適合作為跨平台 Script 的預設值。
可以使用以下指令查看 Bash 的實際位置:
{{CODE_BLOCK_35}}
可能輸出:
{{CODE_BLOCK_36}}
或:
{{CODE_BLOCK_37}}
---
## 8. `/bin/bash` 與 `/usr/bin/env bash` 的差異
|項目|`#!/bin/bash`|`#!/usr/bin/env bash`|
|---|---|---|
|Bash 來源|固定 `/bin/bash`|從 `PATH` 尋找|
|可攜性|較低|較高|
|執行版本|較固定|依環境而定|
|是否受 `PATH` 影響|否|是|
|適合情境|固定 Server、Container|開發工具、跨平台專案|
如果執行環境完全可控,可以使用:
{{CODE_BLOCK_38}}
如果 Script 需要在不同 Linux、macOS 或開發環境中使用,可以考慮:
{{CODE_BLOCK_39}}
---
## 9. macOS 的 Bash 版本
macOS 內建的 Bash 通常位於:
{{CODE_BLOCK_40}}
但內建版本可能較舊。
使用 Homebrew 安裝新版 Bash:
{{CODE_BLOCK_41}}
Apple Silicon Mac 常見路徑:
{{CODE_BLOCK_42}}
Intel Mac 常見路徑:
{{CODE_BLOCK_43}}
檢查目前 Bash 位置:
{{CODE_BLOCK_44}}
檢查 Bash 版本:
{{CODE_BLOCK_45}}
如果使用:
{{CODE_BLOCK_46}}
通常會執行 macOS 內建 Bash。
如果使用:
{{CODE_BLOCK_47}}
則會執行 `PATH` 中最先找到的 Bash。
---
## 10. Shebang 與 Script 參數
不建議在 Shebang 中加入多個參數:
{{CODE_BLOCK_48}}
部分系統可能會將:
{{CODE_BLOCK_49}}
視為完整的程式名稱,而不是 `bash` 加上 `-e` 參數。
比較穩定的方式是將選項放在 Script 內容中:
{{CODE_BLOCK_50}}
各選項的作用:
|選項|說明|
|---|---|
|`-e`|指令執行失敗時停止|
|`-u`|使用未定義變數時報錯|
|`-o pipefail`|Pipeline 中任一指令失敗即視為失敗|
|`-E`|讓 `ERR` Trap 可以在函式等環境中繼承|
---
## 11. 推薦的 Bash Script 開頭
跨平台開發工具可以使用:
{{CODE_BLOCK_51}}
固定 Linux、Server 或 Container 環境可以使用:
{{CODE_BLOCK_52}}
簡單的 Script 不一定需要啟用所有嚴格模式。
例如:
{{CODE_BLOCK_53}}
應依照 Script 的錯誤處理需求選擇適合的設定。
---
## 12. 常見問題
### 為什麼 `./script.sh` 可以,但 `sh script.sh` 不行?
因為:
{{CODE_BLOCK_54}}
會根據 Shebang 使用 Bash。
{{CODE_BLOCK_55}}
則會忽略 Shebang,強制使用 `sh`。
如果 Script 包含 Bash 專屬語法,使用 `sh` 就可能失敗。
### `.sh` 副檔名會決定使用哪個 Shell 嗎?
不會。
以下檔名都可以是 Bash Script:
{{CODE_BLOCK_56}}
真正決定 Interpreter 的是:
- 使用 `./script` 時的 Shebang
- 命令列明確指定的 `bash` 或 `sh`
### 為什麼 `bash script.sh` 不需要執行權限?
因為真正被執行的是 `bash`。
`script.sh` 只是 Bash 讀取的輸入檔案,因此只需要讀取權限。
### 為什麼 `./script.sh` 需要執行權限?
因為作業系統會將 `script.sh` 視為可執行檔案,讀取其 Shebang 後再啟動對應的 Interpreter。
---
## 13. 語法檢查與除錯
在執行前檢查 Bash 語法:
{{CODE_BLOCK_57}}
如果沒有輸出,通常代表沒有發現語法錯誤。
顯示實際執行的指令:
{{CODE_BLOCK_58}}
也可以在 Script 中暫時加入:
{{CODE_BLOCK_59}}
停止顯示執行指令:
{{CODE_BLOCK_60}}
確認 Script 第一行:
{{CODE_BLOCK_61}}
查看是否包含 Windows 換行字元:
{{CODE_BLOCK_62}}
如果 Script 使用 CRLF,Shebang 可能被解析成:
{{CODE_BLOCK_63}}
可以轉換為 Unix 換行格式:
{{CODE_BLOCK_64}}
---
## 重點整理
- Shebang 是 Script 第一行的 `#!` 宣告。
- Shebang 用來指定執行 Script 的 Interpreter。
- `./script.sh` 會根據 Shebang 執行。
- `bash script.sh` 會強制使用 Bash。
- `sh script.sh` 會強制使用 `sh` 並忽略 Shebang。
- `.sh` 副檔名不會決定使用哪一個 Shell。
- Bash Script 不應隨意使用 `sh script.sh` 執行。
- 跨平台 Script 通常使用 `#!/usr/bin/env bash`。
- 固定 Linux 環境可以使用 `#!/bin/bash`。
- Script 執行選項建議寫在內容中,不要放在 Shebang。
- 可以使用 `bash -n script.sh` 進行語法檢查。
---
## 延伸閱讀
- sh script.sh vs ./script.sh Execution Differences — `sh script.sh` 與 `./script.sh` 執行差異的精簡版整理。
- shell 快捷鍵指南 — 終端機日常操作快捷鍵。