特殊变量 #
一、位置参数变量 #
1.1 基本位置参数 #
| 变量 | 说明 |
|---|---|
| $0 | 脚本名称 |
| $1-$9 | 第1到第9个参数 |
| ${10}-$ | 第10个及之后的参数 |
| $# | 参数个数 |
| $* | 所有参数(作为单个字符串) |
| $@ | 所有参数(作为独立字符串) |
1.2 使用示例 #
创建脚本 params.sh:
bash
#!/bin/bash
echo "脚本名称: $0"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "第三个参数: $3"
echo "参数个数: $#"
echo "所有参数: $*"
echo "所有参数: $@"
执行脚本:
bash
$ ./params.sh a b c d e
脚本名称: ./params.sh
第一个参数: a
第二个参数: b
第三个参数: c
参数个数: 5
所有参数: a b c d e
所有参数: a b c d e
1.3 $* 与 $@ 的区别 #
bash
#!/bin/bash
# diff.sh
echo "使用 \$* 遍历:"
for arg in "$*"; do
echo " 参数: $arg"
done
echo "使用 \$@ 遍历:"
for arg in "$@"; do
echo " 参数: $arg"
done
执行结果:
bash
$ ./diff.sh "a b" c d
使用 $* 遍历:
参数: a b c d # 所有参数作为一个整体
使用 $@ 遍历:
参数: a b # 保持原参数结构
参数: c
参数: d
1.4 超过9个参数 #
bash
#!/bin/bash
echo "第10个参数: ${10}"
echo "第11个参数: ${11}"
# 遍历所有参数
for arg in "$@"; do
echo "参数: $arg"
done
二、shift命令 #
2.1 基本用法 #
shift命令用于移动位置参数:
bash
#!/bin/bash
echo "原始参数: $@"
echo "参数个数: $#"
shift
echo "shift后: $@"
echo "参数个数: $#"
shift 2
echo "shift 2后: $@"
echo "参数个数: $#"
执行结果:
bash
$ ./shift.sh a b c d e
原始参数: a b c d e
参数个数: 5
shift后: b c d e
参数个数: 4
shift 2后: d e
参数个数: 2
2.2 处理命令行选项 #
bash
#!/bin/bash
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
echo "用法: $0 [选项]"
echo " -h, --help 显示帮助"
echo " -v, --version 显示版本"
echo " -f, --file 指定文件"
exit 0
;;
-v|--version)
echo "版本: 1.0.0"
shift
;;
-f|--file)
file="$2"
echo "文件: $file"
shift 2
;;
*)
echo "未知选项: $1"
shift
;;
esac
done
三、状态变量 #
3.1 退出状态 $? #
$? 保存上一个命令的退出状态:
bash
# 成功命令
true
echo $? # 输出: 0
# 失败命令
false
echo $? # 输出: 1
# 命令不存在
nonexistent_command
echo $? # 输出: 127
# 测试文件
test -f /etc/passwd
echo $? # 输出: 0(文件存在)
test -f /nonexistent
echo $? # 输出: 1(文件不存在)
3.2 常见退出状态码 #
| 状态码 | 说明 |
|---|---|
| 0 | 成功 |
| 1 | 一般错误 |
| 2 | 误用命令 |
| 126 | 命令不可执行 |
| 127 | 命令未找到 |
| 128 | 退出参数无效 |
| 128+n | 信号n导致的退出 |
| 130 | Ctrl+C终止(128+2) |
| 255 | 退出码超出范围 |
3.3 自定义退出状态 #
bash
#!/bin/bash
check_file() {
if [[ -f "$1" ]]; then
return 0 # 成功
else
return 1 # 失败
fi
}
check_file "/etc/passwd"
if [[ $? -eq 0 ]]; then
echo "文件存在"
else
echo "文件不存在"
fi
四、进程变量 #
4.1 当前进程ID $$ #
bash
#!/bin/bash
echo "当前进程ID: $$"
echo "当前进程信息:"
ps -p $$
# 创建临时文件
temp_file="/tmp/script_$$.tmp"
echo "临时文件: $temp_file"
# 清理临时文件
trap "rm -f $temp_file" EXIT
4.2 后台进程ID $! #
bash
#!/bin/bash
# 后台执行命令
sleep 10 &
echo "后台进程ID: $!"
# 等待后台进程
wait $!
echo "后台进程完成"
4.3 父进程ID $PPID #
bash
#!/bin/bash
echo "当前进程ID: $$"
echo "父进程ID: $PPID"
echo "父进程信息:"
ps -p $PPID
五、其他特殊变量 #
5.1 当前Shell选项 $- #
bash
#!/bin/bash
echo "当前Shell选项: $-"
# 常见选项说明
# h: hashall
# i: interactive
# m: monitor
# s: sourced
# B: braceexpand
# H: histexpand
5.2 上次执行的最后一个参数 $_ #
bash
#!/bin/bash
echo "第一个参数" "第二个参数" "第三个参数"
echo "最后一个参数: $_" # 输出: 第三个参数
ls /etc/passwd
echo "最后一个参数: $_" # 输出: /etc/passwd
5.3 Bash进程ID $BASHPID #
bash
#!/bin/bash
echo "当前Bash进程ID: $BASHPID"
echo "与\$\$比较: $$"
# 在子Shell中
(
echo "子Shell BASHPID: $BASHPID"
echo "子Shell \$\$: $$"
)
六、特殊变量综合示例 #
6.1 脚本信息显示 #
bash
#!/bin/bash
#
# 显示脚本和执行信息
#
echo "======================================"
echo "脚本执行信息"
echo "======================================"
echo "脚本名称: $0"
echo "脚本目录: $(cd "$(dirname "$0")" && pwd)"
echo "脚本PID: $$"
echo "父进程PID: $PPID"
echo "执行用户: $USER"
echo "执行时间: $(date)"
echo "======================================"
echo "参数信息"
echo "======================================"
echo "参数个数: $#"
echo "参数列表: $@"
echo "======================================"
6.2 参数处理脚本 #
bash
#!/bin/bash
#
# 参数处理示例脚本
#
# 显示帮助
show_help() {
cat << EOF
用法: $0 [选项] 文件...
选项:
-h, --help 显示帮助信息
-v, --verbose 显示详细输出
-o, --output 指定输出文件
-n, --number 指定数字
示例:
$0 -v -o result.txt input.txt
$0 --verbose --output=out.txt file1 file2
EOF
}
# 默认值
verbose=false
output=""
number=0
# 解析参数
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_help
exit 0
;;
-v|--verbose)
verbose=true
shift
;;
-o|--output)
output="$2"
shift 2
;;
-n|--number)
number="$2"
shift 2
;;
--)
shift
break
;;
-*)
echo "错误: 未知选项 $1" >&2
show_help
exit 1
;;
*)
break
;;
esac
done
# 剩余参数作为文件
files=("$@")
# 显示配置
if [[ "$verbose" == true ]]; then
echo "详细模式: 开启"
echo "输出文件: ${output:-标准输出}"
echo "数字: $number"
echo "输入文件: ${files[*]}"
fi
6.3 临时文件管理 #
bash
#!/bin/bash
# 创建临时目录
TEMP_DIR=$(mktemp -d)
echo "临时目录: $TEMP_DIR"
# 创建临时文件
TEMP_FILE="${TEMP_DIR}/data_$$.tmp"
echo "临时文件: $TEMP_FILE"
# 清理函数
cleanup() {
echo "清理临时文件..."
rm -rf "$TEMP_DIR"
}
# 注册退出时清理
trap cleanup EXIT
# 使用临时文件
echo "写入数据" > "$TEMP_FILE"
cat "$TEMP_FILE"
# 脚本结束自动清理
七、特殊变量速查表 #
7.1 位置参数 #
| 变量 | 说明 | 示例 |
|---|---|---|
| $0 | 脚本名称 | ./script.sh |
| $1-$9 | 第1-9个参数 | $1, $2 |
| $ | 第n个参数 | $ |
| $# | 参数个数 | 5 |
| $* | 所有参数 | “a b c” |
| $@ | 所有参数 | “a” “b” “c” |
7.2 状态变量 #
| 变量 | 说明 | 示例 |
|---|---|---|
| $? | 上命令退出状态 | 0, 1, 127 |
| $$ | 当前进程ID | 12345 |
| $! | 后台进程ID | 12346 |
| $PPID | 父进程ID | 1000 |
7.3 其他变量 #
| 变量 | 说明 |
|---|---|
| $- | 当前Shell选项 |
| $_ | 上次执行的最后一个参数 |
| $BASHPID | Bash进程ID |
八、总结 #
8.1 关键要点 #
$0-$n用于获取脚本参数$#获取参数个数$@和$*获取所有参数(引号中有区别)$?获取命令退出状态$$获取当前进程ID
8.2 下一步 #
你已经掌握了特殊变量的使用,接下来让我们学习 环境变量,了解系统环境变量的配置!
最后更新:2026-03-27