set -e 的双刃剑
面试官问:
“你的脚本里用了 set -e。 假设你有一行命令是检查日志里有没有报错:grep "ERROR" run.log。
如果日志里没有 ERROR,这行命令的返回码(Exit Code)是多少?
结合 set -e,这时候你的脚本会发生什么?
如果我不希望脚本因为‘没找到错误’而崩溃退出,我该怎么写这行代码?”
❌ 你的错误点
你的回答:“面试官只问了我一个问题的话,我肯定会回答正常退出。”
事实是:它返回的是 1 (异常/失败)。
在 Linux Shell 中:
0 = 真 (True) / 成功 (Success)。
非 0 (1, 2, 127...) = 假 (False) / 失败 (Failure)。
grep 的特殊逻辑:
找到了 (Match Found) -> 返回 0 (代表“是的,我找到了”)。
没找到 (No Match) -> 返回 1 (代表“不,没找到”)。
💥 灾难推演 (为什么这是个坑?)
场景:你的自动化测试跑得很完美,日志里完全没有 ERROR。你是想检查有没有错,结果因为太完美(没找到错),grep 觉得这事儿“不成立”,返回了 1。
命令:grep "ERROR" run.log
实际情况:日志很干净,没找到 "ERROR"。
返回码:1。
set -e 的反应:它看到上一行命令返回了非 0,判定为 “脚本执行出错”。
结果:脚本立即自杀退出。
讽刺吗? 你的测试明明通过了,却因为“找不到错误日志”,导致整个 Jenkins 构建变成红色(Failure)。这就是不理解 grep 返回值的代价。
✅ 正确的回答 (P7 标准)
请把这三个问题的答案背下来:
Q1. 返回码是多少?
“如果日志里没有 'ERROR',grep 会视为‘未匹配’,返回状态码 1。”
Q2. 脚本会发生什么?
“由于开启了 set -e,Shell 会捕捉到这个 非 0 返回码,误判为脚本执行失败,导致脚本立即终止退出。这会导致 CI 构建误报失败。”
Q3. 怎么修复?(防崩溃写法)
“我们需要‘吞掉’这个错误码。最常用的写法是利用逻辑或 (||): grep "ERROR" run.log || true 这样,即使 grep 返回 1,|| 后面的 true (返回 0) 会执行,整个命令组合的最终返回码就是 0,脚本就能继续跑下去了。”

浙公网安备 33010602011771号