Shell 的核心工作很简单:你输入命令,它执行,然后告诉你结果。理解这个"输入-执行-反馈"的循环,是用好命令行的基础。
命令是如何执行的
在终端提示符(通常是 $ 或 #)后输入命令,按回车,Shell 就会启动对应的程序:
$ ls -l file.txt
-rw-r--r-- 1 user group 1024 Jan 15 09:30 file.txt
这里发生了三件事:
- 解析:Shell 识别出
ls是要执行的程序,-l和file.txt是参数 - 执行:操作系统运行
/bin/ls,把参数传给它 - 反馈:程序运行结果返回到终端显示
三种反馈形式
命令执行后,反馈不只有屏幕上的文字,实际上有三个独立的通道:
1. 标准输出(stdout)
命令的正常结果,默认显示在屏幕上。可以用 > 保存到文件:
$ date > today.txt # 输出被写入文件,屏幕不显示
2. 标准错误(stderr)
出错信息单独走一个通道,默认也显示在屏幕,但可以用 2> 单独捕获:
$ ls /root
ls: cannot open directory '/root': Permission denied # 这是 stderr
$ ls /root 2> error.log # 错误信息写入文件,正常输出仍显示
3. 退出状态码(exit code)
每个命令执行完都会返回一个数字(0-255),0 表示成功,非 0 表示失败。通过 $? 查看:
$ ls /etc/passwd
/etc/passwd
$ echo $? # 显示 0,表示上条命令成功
$ ls /不存在的文件
ls: cannot access '/不存在的文件': No such file or directory
$ echo $? # 显示 2,表示出错
实用技巧:在脚本中判断命令是否成功,不要看屏幕有没有字,要看 $? 是否为 0:
mkdir /backup 2>/dev/null
if [ $? -eq 0 ]; then
echo "目录创建成功"
else
echo "创建失败(可能已存在或无权限)"
fi
常见误区
- 没输出 ≠ 失败:很多命令成功时沉默(如
cp、mv),只有出错才说话。别光看屏幕有没有字,养成看$?的习惯。 - 错误信息混杂:默认 stdout 和 stderr 都往屏幕挤,看着混乱。需要分别处理时记得用
>和2>。 - 忽略退出码:写自动化脚本时,如果不检查上条命令的
$?,失败了的命令会继续执行,可能把错误数据传给下一步。
小结
记住这个检查清单:
- 命令执行后,先看有没有错误信息(stderr)
- 再用
echo $?确认是否真的成功(exit code 为 0) - 需要保存结果时,区分是要保存正常输出(
>)还是错误信息(2>)还是两者都要(&>)
掌握这三点,排查命令行问题会快很多。