Shell 腳本中 $ 開頭的特殊變量是參數處理核心。本文系統梳理所有位置參數、特殊變量含義,附帶實戰腳本驗證輸出,建立完整知識體系。
| 變量 | 含義 | 示例值 | 說明 |
|---|---|---|---|
$0 | 腳本名稱/命令名 | ./script.sh | 包含路徑時顯示完整路徑 |
$1-$9 | 第 1-9 個位置參數 | arg1, arg2... | 第 10 個以上用 ${10} |
$# | 位置參數個數 | 3 | 不含 $0 |
$@ | 所有位置參數 (列表) | "arg1" "arg2" "arg3" | 雙引號中保持各參數獨立 |
$* | 所有位置參數 (單字符串) | "arg1 arg2 arg3" | 以 $IFS 首字符連接 |
$$ | 當前 Shell 進程 PID | 12345 | 腳本運行實例標識 |
$? | 上一條命令退出狀態 | 0 (成功) / 非0 (失敗) | 緊跟命令後獲取 |
$! | 最後後台進程 PID | 12346 | cmd & 後獲取 |
$- | 當前 Shell 選項標誌 | himBH | set -o 可查看 |
$_ | 上一命令最後一個參數 | /path/file | Alt+. 可插入 |
#!/bin/bash
# var_demo.sh
echo "=== 位置參數 ==="
echo "腳本名: $0"
echo "參數個數: $#"
echo "參數1: $1"
echo "參數2: $2"
echo "參數3: $3"
echo -e "\n=== 特殊變量 ==="
echo '\$@ (列表):'
for arg in "$@"; do echo " [$arg]"; done
echo '\$* (字符串):'
for arg in "$*"; do echo " [$arg]"; done
echo -e "\n=== 進程相關 ==="
echo "當前 PID: $$"
echo "上一命令退出碼: $?"
# 測試退出碼
true
echo "true 後 \$?: $?"
false
echo "false 後 \$?: $?"
# 後台進程
sleep 1 &
echo "後台 sleep PID: $!"
$ ./var_demo.sh apple banana cherry
=== 位置參數 ===
腳本名: ./var_demo.sh
參數個數: 3
參數1: apple
參數2: banana
參數3: cherry
=== 特殊變量 ===
$@ (列表):
[apple]
[banana]
[cherry]
$* (字符串):
[apple banana cherry]
=== 進程相關 ===
當前 PID: 12345
上一命令退出碼: 0
true 後 $?: 0
false 後 $?: 1
後台 sleep PID: 12346
# 在雙引號中行為不同
func() { for i in "$@"; do echo "[$i]"; done }
func "a b" "c" # $@: ["a b"] ["c"] 保持參數邊界
func "a b" "c" # $*: ["a b c"] 合併為單字符串
# 最佳實踐:遍歷參數始終用 "$@"
for arg in "$@"; do
process "$arg"
done
# shift [n] 將參數左移 n 位
# $1←$2, $2←$3... $#減少 n
# 常用於選項解析
while [ $# -gt 0 ]; do
case $1 in
-f) FILE=$2; shift 2 ;;
-v) VERBOSE=1; shift ;;
*) echo "Unknown: $1"; shift ;;
esac
done
#!/bin/bash
usage() {
echo "Usage: $0 [-f file] [-d dir] [-v]"
exit 1
}
[ $# -eq 0 ] && usage
FILE=""
DIR=""
VERBOSE=0
while getopts "f:d:v" opt; do
case $opt in
f) FILE=$OPTARG ;;
d) DIR=$OPTARG ;;
v) VERBOSE=1 ;;
*) usage ;;
esac
done
shift $((OPTIND-1))
# 剩餘參數在 $@ 中
echo "File: $FILE, Dir: $DIR, Verbose: $VERBOSE"
echo "Remaining args: $@"
$10 錯誤寫法,必須 ${10}$* 不加引號 → 通配符展開、詞分割$? 不立即保存 → 被後續命令覆蓋local 避免變量污染set -euo pipefail 嚴格模式捕獲錯誤精通 Shell 特殊變量,編寫健壯、靈活、可維護的自動化腳本。