特殊变量 #

一、位置参数变量 #

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