Shell 脚本防坑指南:set -euo pipefail 与常见死法实录

举报
yd_216677863 发表于 2026/10/23 16:16:52 2026/10/23
【摘要】 写 Shell 脚本十年,见过太多「在我机器上明明能跑」的灵异现场。九成问题出在脚本没有防御性设置。本文把最关键的几条保命符一次讲透。一、三件套:set -euo pipefail#!/bin/bashset -euo pipefail- -e:任何命令失败立刻退出,不让错误滚雪球- -u:引用未定义变量直接报错,抓住拼写错误- -o pipefail:管道中任何一环失败都算整体失败。没有它...

写 Shell 脚本十年,见过太多「在我机器上明明能跑」的灵异现场。九成问题出在脚本没有防御性设置。本文把最关键的几条保命符一次讲透。


一、三件套:set -euo pipefail

#!/bin/bash

set -euo pipefail


- -e:任何命令失败立刻退出,不让错误滚雪球

- -u:引用未定义变量直接报错,抓住拼写错误

- -o pipefail:管道中任何一环失败都算整体失败。没有它,cmd1 | cmd2 里 cmd1 崩了,退出码会被 cmd2 的成功覆盖


二、常见死法实录

死法1:变量没加引号。rm -rf $DIR 在 DIR 为空时等于 rm -rf,直接清空当前目录。正确写法 rm -rf "$DIR"。

死法2:cd 失败继续跑。cd /data && rm -rf tmp 看着安全,但若上一行 cd 失败且没 set -e,后面的相对路径操作全跑在错误目录。cd ... || exit 1 双保险。

死法3:管道退出码被吞。gzip -t backup.gz | grep -q error 返回 0 就以为备份健康——gzip 崩了退出码也被 grep 的成功覆盖。pipefail 专治这个。

死法4:$? 用晚了。中间插了一行 echo,if [ $? -eq 0 ] 检查的就是 echo 的退出码。


三、调试三板斧

- bash -n script.sh:只做语法检查不执行

- bash -x script.sh:打印每条命令再执行

- set -x / set +x:脚本内局部开启关闭,缩小排查范围


四、进阶习惯

- 用 mktemp -d 建临时目录并 trap 'rm -rf "$TMPDIR"' EXIT 兜底清理

- 本地变量一律 local(函数内)

- shellcheck 静态扫描接入 CI,一劳永逸


防御性脚本写法的本质:让失败尽早、尽响亮地暴露。出错不可怕,静默出错才致命。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。