Shell中&&和||基于命令退出码实现短路执行:&&在前命令成功(0)时执行后命令,||在前命令失败(非0)时执行后命令;二者均只依赖紧邻左侧命令状态,不累积结果。

Shell 中用 && 和 || 实现命令的条件短路执行,核心在于利用命令的退出状态($?):成功为 0,失败为非 0。这两个符号不判断“真假值”本身,而是依据上一条命令是否成功来决定是否执行下一条。
理解短路机制的关键逻辑
Shell 的短路不是靠布尔表达式求值,而是靠命令执行后的退出码跳转:
- && 是“成功才继续”:前一个命令返回 0(成功),后续命令才运行;一旦某条失败(非 0),后面全部跳过
- || 是“失败才继续”:前一个命令返回非 0(失败),后续命令才运行;一旦某条成功(0),后面全部跳过
- 它们都只看紧邻左侧命令的退出状态,不累积或合并多个结果
- 这种行为和 C/Python 中的
&&、||一致,属于“短路求值”
常用 && 组合:串联依赖型操作
适合需要按顺序完成、且每步都必须成功的场景,比如部署、清理、安装流程:
-
mkdir -p /data/logs && touch /data/logs/app.log && chown app:app /data/logs/app.log只有目录创建成功,才建日志文件;只有文件创建成功,才改属主。任一失败,后续不执行 -
cp config.conf /etc/myapp/ && systemctl reload myapp && echo "Config updated"配置复制失败时,不会误重启服务;重载成功后才打印提示 - 注意:
&&不能直接用于 if 条件内部的复合测试(如[ -f a ] && [ -r a ]必须写成两个独立测试,或用[[ ]]语法)
常用 || 组合:提供 fallback 或错误处理
适合容错、兜底、或二选一的场景,比如检查存在性、降级执行、报错提示:
-
ls /var/log/nginx/access.log || echo "Nginx log not found"日志不存在时输出提示,存在则静默(不执行右边) -
command -v jq >/dev/null || { echo "jq missing, installing..."; apt-get install -y jq; }检测工具缺失时才安装,存在则跳过整个块 -
ping -c1 google.com &>/dev/null || echo "Network unreachable" | logger -t netcheck网络不通时记录日志,通则无动作
组合使用 && 和 || 实现三态逻辑
类似“if-else”,但更轻量,常用于单行判断:
-
mkdir /tmp/test && echo "OK" || echo "Failed"注意:这并非严格等价于 if-else —— 如果mkdir成功但echo "OK"因某种原因失败(极少见),也会触发echo "Failed"。更稳妥写法是:if mkdir /tmp/test; then echo "OK"; else echo "Failed"; fi - 真正安全的单行替代:
mkdir /tmp/test && { echo "OK"; } || { echo "Failed"; }用花括号把成功/失败分支各自包成一个命令组,避免中间命令干扰逻辑 - 常见模式:
command || { cleanup; exit 1; }—— 失败时统一清理并退出

















