整理常用 Shell (sh, bash, zsh) 在語法、功能上的差異與相容性,方便參考。
| 類型 | sh (POSIX) | bash | zsh | 備註 |
|---|---|---|---|---|
| Shebang | #!/bin/sh |
#!/bin/bash |
#!/bin/zsh |
建議腳本跨平台用 #!/bin/sh |
| 變數宣告 | name=value |
相同 | 相同 | 不能有空格 |
| 字串插值 | "Hello $name" |
相同 | 相同 | 都支援 |
| 命令替換 | `date` 或 $(date) |
相同 | 相同 | 建議用 $( ) |
| 條件判斷 | [ "$a" = "$b" ] |
[ "$a" = "$b" ] 或 [[ $a == $b ]] |
[ "$a" = "$b" ] 或 [[ $a = $b ]] |
[[ ... ]] 不是 POSIX 的寫法 |
| 邏輯運算 | [ "$a" = 1 ] && [ "$b" = 2 ] |
[[ $a = 1 && $b = 2 ]] |
相同 | [[ ... && ... ]] 非 POSIX |
| 數學運算 | $((1+2)) |
((i++)) / $((1+2)) |
((i++)) / $((1+2)) |
POSIX sh 只能 $(( )) |
| 陣列 | ❌ 不支援 | arr=(a b c) → ${arr[0]} |
arr=(a b c) → ${arr[1]} |
Bash 陣列從 0 起算,Zsh 從 1 起算 |
| 關聯陣列 key=value | ❌ | declare -A map; map[key]=val |
typeset -A map; map[key]=val |
POSIX sh 沒有 |
| brace expansion | ❌ | {1..5} |
{1..5} |
POSIX sh 不支援 |
| 迴圈 for | for i in 1 2 3; do ...; done |
for i in {1..3}; do ...; done |
brace expansion 會展開整個序列 | {1..3} 不是 POSIX |
| 函數定義 | foo() { ... } |
foo() { ... } 或 function foo { ... } |
相同 | function foo {} 不是 POSIX |
| 字串長度 | ${#var} |
相同 | 相同 | |
| 字串比較 | = |
== / = |
== / = (glob) |
POSIX sh 只能用 = |
| 大小寫轉換 | ❌ | ${var^^} / ${var,,} |
${(U)var} / ${(L)var} |
Bash/Zsh 特殊功能 |
| 字串切割 | ${var%pattern} / ${var#pattern} |
支援更多:${var^^} (大寫) |
支援更多::${(U)var} |
POSIX 只有 % # |
| printf / echo | printf 標準,echo 不一定支援 -e |
echo -e 可用 |
echo -e 可能無效,用 print |
建議用 printf |
| 測試檔案 | [ -f file ] |
相同 | 相同 | |
| 正則比對 | ❌ | [[ string =~ regex ]] |
[[ string =~ regex ]] 但 regex 語法不同 |
POSIX sh 無 regex 功能 |
| 展開 (globbing) | 基本 * ? [ ] |
需 shopt -s globstar |
Zsh 預設更強大 (e.g. **/*.txt) |
Zsh glob 功能最強 |
| 補全 (tab) | ❌ | 需 bash-completion |
內建強大補全 | 互動環境差異,不影響 script |
| 錯誤處理 | set -e |
相同,加強版 set -o pipefail |
相同 | pipefail 不是 POSIX |
| 信號處理 | trap 'cmd' INT TERM |
相同 | 相同 | |
| source 檔案 | . file |
source file / . file |
source file / . file |
POSIX sh 用 . |
| 目錄堆疊 | ❌ | pushd / popd |
pushd / popd |
POSIX sh 無目錄堆疊功能 |
| 互動功能 | ❌ | readline、history、completion | history、completion、prompt customization | Zsh 提供最強互動功能 |
| local / typeset | ❌ | local / typeset |
local / typeset |
POSIX sh 不支援函數內局部變數 |
- sh
- POSIX,相容性最好,但功能有限。
- 如果要製作跨平台的 script,就使用標準的 POSIX 語法
- bash
- 增強 POSIX,支援陣列、關聯陣列、
[[ ]]、brace expansion、Bashisms。 - 一般在 mac/linux,可使用 bash script
- 增強 POSIX,支援陣列、關聯陣列、
- zsh
- 幾乎包含 Bash 功能,互動功能更強(prompt、補全、glob、history)
- 陣列索引從 1 開始,部分語法行為不同。
- 使用者互動操作時,可使用 zsh
沒有留言:
張貼留言