set -e 使脚本在任意简单命令返回非零退出码时立即终止;它对 &&/|| 后命令、if/while 条件命令、! 取反命令等不生效,推荐与 -u 和 pipefail 联用以提升健壮性。

在 Linux Shell 脚本中,set -e 是让脚本在任意命令返回非零退出状态时立即终止执行的最简方式。它不是“检测错误”,而是严格依据命令的退出码(exit code)做判断:只要不是 0,就停。
什么时候 set -e 真正起作用
它只对“简单命令”生效,比如:
- 单独一行的普通命令(
cp file1 file2、mkdir /tmp/test) - 管道中最后一个命令(
cat log.txt | grep "ERROR"中的grep) - 命令替换内部的命令(
val=$(ls /missing)中的ls)
但以下情况不会触发退出:
- 命令后接
&&或||(如grep "WARN" app.log || echo "no warning") - 出现在
if、while、until条件部分的命令(如if false; then ...; fi) - 以
!开头的命令(如! ping -c1 host,失败反而变成功)
怎么安全启用 set -e
推荐在脚本第一行 shebang 后立即启用,并搭配其他防护选项:
#!/bin/bash set -euo pipefail
其中:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
-
-e:出错即停 -
-u:引用未定义变量时报错(防拼写错误) -
-o pipefail:让管道中任一命令失败,整个管道就失败(默认只看最后一个)
如何处理“预期会失败”的命令
有些命令失败是正常逻辑(比如用 grep 查日志里有没有 ERROR),不希望因此中断脚本。常见写法有:
- 加
|| true:保证整行返回 0grep "ERROR" app.log || true - 用
if显式判断并处理:if ! grep "FATAL" app.log; then echo "OK: no fatal error"; fi - 临时关闭再恢复(慎用):
set +e; some_unreliable_cmd; set -e
调试 set -e 相关问题
脚本突然提前退出?开启详细追踪定位:
set -euxo pipefail
-x 会逐行打印实际执行的命令和参数,方便看到哪条命令悄悄返回了非 0 值。注意:grep 找不到内容返回 1、test -f missing.txt 返回 1,这些都属于“正常失败”,但会被 set -e 当作异常终止。










