Shell 实用技巧:快速获取上一次命令的参数(附特殊变量全解析)
概述
在 Shell(Bash/Zsh 这些)里操作的时候,咱们经常会碰到“重复使用上一次命令的参数”的情况——比如刚用 cd /home/user/projects 进了项目目录,接着想执行 ls /home/user/projects 看里面有什么,这时候把路径再敲一遍既麻烦又容易敲错。
其实 Shell 早就给了“一键拿到上一次命令参数”的办法,不用手动复制粘贴;另外还有一整套“特殊变量”,能帮我们快速拿到参数个数、进程 ID、命令执行结果这些关键信息。这篇就从“实用技巧”和“知识储备”两个角度,把“怎么拿上一次命令参数”和“Shell 特殊变量”拆开讲清楚,让命令行操作更顺手。
一、核心技巧:3 种方式获取上一次命令的参数
拿上一次命令的参数,最常用的是快捷键和特殊变量——前者适合“随手复用”,后者适合“脚本或复杂场景”,按需要挑就行。
1. 快捷键:Alt + .(最直观,即时复用)
这是 Shell 内置的“黄金快捷键”,不用记命令,按 Alt + 小数点 就能直接在当前命令行插入“上一次命令的最后一个参数”,效率最高。
操作步骤与示例:
# 步骤 1:执行一个带参数的命令(如 cd 到项目目录)
cd /home/user/projects/my-app
# 步骤 2:输入 ls 后,按下 Alt + .(小数点)
ls [按下 Alt+. 后,自动插入 /home/user/projects/my-app]
# 最终命令自动变为(无需手动输入路径)
ls /home/user/projects/my-app
补充说明:
- 多参数场景:如果上一次命令有多个参数(比如 cp file1.txt file2.txt /tmp),Alt + . 插的是“最后一个参数”(也就是 /tmp);
- 连续使用:连按几次 Alt + .,会依次回溯“上上次的最后一个参数”“上上上次的最后一个参数”(第一次按是上 1 次,第二次按是上 2 次,依次类推);
- 兼容性:Bash 和 Zsh 都支持这个快捷键,MacOS 终端要注意:部分键盘得用 Option + .(Option 键就对应 Windows 的 Alt 键)。
2. 特殊变量:$_(脚本与命令行通用)
$_ 是 Shell 内置的特殊变量,代表“上一个命令的最后一个参数”,在命令行或脚本里都能直接用,比快捷键更灵活(能嵌套进别的命令里)。
命令行示例:
# 步骤 1:执行带参数的命令
mkdir -p /tmp/test/logs
# 步骤 2:用 $_ 获取上一次命令的最后一个参数(/tmp/test/logs)
cd $_ # 等价于 cd /tmp/test/logs
ls $_ # 等价于 ls /tmp/test/logs
# 步骤 3:嵌套使用(把上一次参数作为新命令的一部分)
echo "日志目录路径:$_" # 输出 "日志目录路径:/tmp/test/logs"
脚本示例(实用场景): 在脚本里,$_ 能用来“复用前一步的参数,少定义几个变量”:
#!/bin/bash
# 脚本功能:创建目录并进入该目录
# 步骤 1:接收用户传入的目录路径参数,创建目录
mkdir -p "$1"
# 步骤 2:用 $_ 获取上一步的参数(即 $1 传入的路径),进入目录
cd $_
# 步骤 3:提示当前目录
echo "已进入目录:$(pwd)"
执行脚本:
chmod +x cd_and_mkdir.sh
./cd_and_mkdir.sh /home/user/new-dir # 输出 "已进入目录:/home/user/new-dir"
3. 历史扩展:!$(命令行专用,需注意场景)
!$ 是 Shell 的“历史扩展符”,功能和 $_ 类似,也代表“上一次命令的最后一个参数”,不过它用时是先“展开成具体参数”再执行,适合纯命令行场景。
示例:
# 步骤 1:执行带参数的命令
git add README.md
# 步骤 2:用 !$ 获取上一次的参数(README.md)
git commit -m "更新文档" !$ # 展开后为 git commit -m "更新文档" README.md
# 步骤 3:查看展开过程(加 echo 可预览命令,避免误执行)
echo git commit !$ # 输出 "git commit README.md"(仅预览,不执行)
二、知识储备:Shell 常用特殊变量全解析
除了 $_,Shell 还有一整套“特殊变量”,不用定义就能直接用,覆盖“参数处理”“进程信息”“命令结果”这些核心场景,是写脚本和高效用命令行的基础。
下面按“使用场景”分类,整理出 Bash/Zsh 通用的一些高频特殊变量:
1. 命令行参数相关变量(脚本 / 函数常用)
这类变量用来处理“传给脚本或函数的参数”,是脚本开发的核心变量。
| 特殊变量 | 含义 | 示例(脚本中) |
|---|---|---|
| $0 | 当前 Shell 名称(如 bash/zsh)或脚本的文件名(含路径,取决于执行方式) | 执行 ./test.sh 时,$0 为 ./test.sh;执行 bash test.sh 时,$0 为 test.sh |
| $n | 传递给脚本 / 函数的第 n 个参数(n 为数字,如 $1 是第一个参数,$2 是第二个) | 执行 ./test.sh a b c 时,$1=a、$2=b、$3=c |
| $# | 传递给脚本 / 函数的 “参数总个数”(不含 $0) | 执行 ./test.sh a b c 时,$#=3 |
| $@ | 所有参数的 “列表”,每个参数独立加双引号(适合循环处理参数,避免空格问题) | 执行 ./test.sh “a b” c 时,$@ 等价于 “a b” “c”(循环时会拆分为两个参数) |
| $* | 所有参数的 “字符串”,将所有参数用空格连接后加双引号(适合整体处理参数) | 执行 ./test.sh “a b” c 时,$* 等价于 “a b c”(整体视为一个字符串) |
实用示例(参数遍历):
#!/bin/bash
# 脚本功能:遍历并打印所有传入的参数
echo "参数总个数:$#"
echo "----------------"
# 用 $@ 遍历参数(推荐,支持含空格的参数)
echo "用 \$@ 遍历参数:"
for arg in "$@"; do
echo "参数:$arg"
done
echo "----------------"
# 用 $* 遍历参数(对比,含空格的参数会被拆分)
echo "用 \$* 遍历参数:"
for arg in "$*"; do
echo "参数:$arg"
done
执行脚本:
./loop_args.sh "hello world" linux shell
输出结果:
参数总个数:3
----------------
用 $@ 遍历参数:
参数:hello world
参数:linux
参数:shell
----------------
用 $* 遍历参数:
参数:hello world linux shell
2. 进程与状态相关变量(调试 / 监控常用)
这类变量用来拿“当前进程信息”或“上一个命令的执行结果”,调试脚本和监控命令执行状态时特别好用。
| 特殊变量 | 含义 | 示例 |
|---|---|---|
| $$ | 当前脚本 / 命令的 “进程 ID(PID)” | 在脚本中执行 echo “当前脚本 PID:$$“,输出类似 当前脚本 PID:12345 |
| $? | 上一个命令的 “退出状态码”(0 表示执行成功,非 0 表示失败,具体值因命令而异) | 执行 ls /tmp 后,echo $? 输出 0;执行 ls /nonexistent 后,echo $? 输出 2 |
| $! | 上一个 “后台运行命令” 的 PID(仅对后台命令有效,前台命令无值) | 执行 sleep 100 & 后,echo $! 输出后台 sleep 进程的 PID(如 12346) |
实用示例(脚本调试与后台监控):
#!/bin/bash
# 脚本功能:后台运行任务并监控其状态
# 步骤 1:后台执行一个长时间任务(sleep 模拟)
echo "启动后台任务..."
sleep 60 &
# 步骤 2:用 $! 获取后台任务的 PID,用 $$ 获取当前脚本 PID
BACKGROUND_PID=$!
SCRIPT_PID=$$
echo "当前脚本 PID:$SCRIPT_PID"
echo "后台任务 PID:$BACKGROUND_PID"
# 步骤 3:等待后台任务完成,用 $? 查看其退出状态
wait $BACKGROUND_PID
echo "后台任务执行完成,退出状态码:$?" # 输出 0(sleep 正常结束)
三、总结:实用场景与最佳实践
| 需求场景 | 推荐方案 | 优势 |
|---|---|---|
| 命令行中即时复用上一次参数 | Alt + . | 无需输入命令,一键插入,效率最高 |
| 脚本中复用前一步命令的参数 | $_ | 兼容性好,支持动态获取,适合脚本逻辑 |
| 命令行中预览并复用参数 | !$ + echo | 可先预览展开结果,避免误执行 |
| 脚本中遍历含空格的参数 | ”$@” | 正确处理含空格的参数,不拆分,最安全 |
| 调试脚本,查看命令执行结果 | $? | 快速判断上一步命令是否成功,定位错误 |
| 脚本中监控后台任务 | $! + wait | 获取后台进程 PID,方便后续管理(如 kill 停止) |
掌握这些技巧后,不但能省掉“重复输入参数”的麻烦,还能让脚本写得更简洁(少定义些冗余变量)。建议从“Alt + .”和“$_”开始练,慢慢熟悉其他特殊变量,Shell 操作就越来越高效了。