Shell 脚本健壮性指南:set -e、引号与错误处理

举报
yd_99838092 发表于 2026/11/11 14:20:49 2026/11/11
【摘要】 从 set -e 的陷阱、变量引用加引号到 trap 清理,整理编写可靠 Shell 脚本的常用做法和常见错误。

为什么脚本会“静默失败”

Shell 默认不会因为某条命令失败就退出,变量不加引号会被分词或通配符展开,错误输出可能被忽略。结果是脚本“看起来跑完了”,实际数据或文件已经出错。

1. 开头几行

#!/usr/bin/env bash
set -euo pipefail
  • -e:命令失败立即退出;

    • -u:使用未定义变量时报错;

      • -o pipefail:管道中任一命令失败,整个管道视为失败。

      • 在 if、&&、|| 中,-e 不会触发退出,这符合预期。

    • 2. 变量始终加引号

  • rm -- "$file"
    

    文件名包含空格或通配符时,不加引号会被拆成多个参数,可能误删文件。-- 还能避免文件名以 - 开头被当成选项。

    3. 用 trap 清理临时资源

    tmp=$(mktemp -d)
    trap 'rm -rf "$tmp"' EXIT
    

    脚本异常退出时也能清理临时目录,避免残留。

    4. 显式检查依赖与退出码

    if ! command -v jq >/dev/null 2>&1; then
      echo "jq not found" >&2
      exit 1
    fi
    

    把错误信息输出到 stderr,并用非 0 退出码告诉调用方失败。

    5. 几个常见坑

    1. set -e 下 grep 没匹配会返回 1 导致脚本退出,可用 grep ... || true 或放进 if;
      1. $@ 与 "$@" 行为不同,传递参数时应使用 "$@";
        1. 管道里的赋值发生在子 shell,echo x | read v 之后 $v 可能仍为空;

          1. 用 2>/dev/null 掩盖错误会让排查变难,至少保留关键错误。

          2. 6. 调试技巧

        2. bash -x script.sh     # 打印执行过程
          set -x                # 在脚本内部开启
          

          配合 set -e 可以快速定位出错的命令。

          小结

          健壮的 Shell 脚本通常具备四件事:set -euo pipefail、变量加引号、trap 清理资源、显式检查依赖和退出码。把这些习惯固定下来,能避免大多数“跑完了但结果是错的”问题。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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