推荐直接用命令退出状态驱动流程,如if ping -c1 192.168.1.1 >/dev/null; then echo "通"; else echo "不通"; fi;需复用或区分错误类型时才用$?,且必须紧接目标命令后读取。

直接用命令本身的退出状态来驱动流程,比先取 $? 再判断更简洁、更可靠。
用 if 直接判断命令状态
Shell 的 if 语句本质就是检查命令的退出码:返回 0 就走 then 分支,非 0 就走 else(或跳过)。
if ping -c1 192.168.1.1 >/dev/null; then echo "通"; else echo "不通"; fiif [ -f /etc/passwd ]; then echo "文件存在"; else echo "文件不存在"; fiif systemctl is-active --quiet sshd; then echo "sshd 正在运行"; fi
这种写法天然避免了 $? 被后续命令覆盖的问题,也不需要额外变量保存,推荐作为默认做法。
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统
需要复用状态码时才用 $?
当一条命令要被多次判断、或需区分多种失败原因时,就得立刻捕获 $?。
- 必须紧接在目标命令之后读取:
ls /tmp/test &>/dev/null; ret=$?; echo "退出码:$ret" - 不能中间插入其他命令,否则 $? 就变成那条命令的退出码了
- 常见误写:
ls /tmp/test &>/dev/null; echo "结果"; ret=$?→ 这里 $? 是 echo 的退出码(通常是 0),不是 ls 的
用 case 区分多种错误类型
如果想对不同非零退出码做不同处理,case 比多个 elif 更清晰。
command_that_might_fail; case $? in 0) echo "成功";; 127) echo "命令没找到";; 126) echo "权限不足";; *) echo "其他错误: $?";; esac- 注意:case 只能匹配上一个命令的 $?,所以 command_that_might_fail 和 case 之间不能有其他命令
逻辑操作符 && 和 || 的快捷用法
适合简单串联或兜底,语义明确,但不适合复杂分支。
-
mkdir /tmp/mydir && cd /tmp/mydir→ 成功才执行下一步 rm /tmp/old.log 2>/dev/null || echo "清理失败,可能文件不存在"- 慎用
&& command1 || command2替代 if-else:如果 command1 返回非 0,command2 才执行;但如果 command1 返回 0 且自身失败(比如内部出错但没设退出码),逻辑可能意外中断










