Jacky's blog
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)
  • 计算机基础
  • 计算机基础

  • 网络

  • 操作系统

  • Shell
    • Shell 学习与使用导航
    • shell 入门指南
    • Shell 执行模型与环境加载
    • Shell 错误处理、调试与资源清理
      • 错误处理与健壮性
        • 严格模式
        • 错误捕获与降级
        • 信号与清理
        • 作业控制
      • 退出状态与严格模式边界
      • 调试与验证
    • Shell 常用命令速查手册
    • Shell 代码片段集合
  • 安全

  • 设计模式

  • cs
  • shell
Jacky
2026-10-26
目录

Shell 错误处理、调试与资源清理

# 错误处理与健壮性

# 严格模式

set -e             # 在适用上下文中遇非零状态退出;存在下述例外
set -u             # 引用未定义变量报错
set -o pipefail    # 管道状态取最右侧非零状态;全成功才是 0
1
2
3

# 错误捕获与降级

if ! command_that_might_fail; then
    echo "命令执行失败" >&2
    exit 1
fi

error_output=$(command 2>&1)              # 捕获 stdout+stderr
result=$(command 2>/dev/null) || result="default"    # 忽略错误并降级
command 2>> error.log                     # 错误追加到日志
1
2
3
4
5
6
7
8

# 信号与清理

temp_file=$(mktemp) || exit 1
cleanup() {
    local status=$?
    trap - EXIT
    rm -f "$temp_file" || printf '%s\n' '清理临时文件失败' >&2
    exit "$status"  # 保留业务失败,不能用 exit 0 掩盖
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
1
2
3
4
5
6
7
8
9
10

# 作业控制

command &        # 后台运行
jobs -l          # 列出后台任务
fg %1            # 移到前台
bg %1            # 前台任务转后台继续
kill %1          # 杀死任务
1
2
3
4
5

# 退出状态与严格模式边界

情况 状态语义与处理
普通命令 通常 0 成功;非零含义由命令定义,立即保存 $?
grep 0 匹配、1 无匹配、2 错误;不能把无匹配当 I/O 故障
diff / cmp 0 相同、1 不同、diff 为 2/cmp 大于 1 表示错误;见 比较指南
! command 将状态取反;if ! command; then rc=$? 得到的是取反后的 0
((count++)) 表达式旧值为 0 时状态为 1;现代 Bash 可因此触发 -e,macOS Bash 3.2 行为有差异;计数用 count=$((count + 1))
默认管道 通常仅取最后一段状态;pipefail 改变状态,不代表管道立即停止

-e 在 if/while/until 条件、!、部分 &&/||、非末段管道等位置受到抑制;函数作为条件或出现在 func || handler 时,函数体内的 -e 也可能被忽略。命令替换中的继承还受 POSIX 模式、inherit_errexit 与版本影响。可复用函数对 mkdir、复制、写文件等关键操作应显式检查,不依赖调用方的选项。

if operation; then
    printf '%s\n' '成功'
else
    status=$?                    # 立即保存真正的失败码
    printf '失败状态: %s\n' "$status" >&2
    exit "$status"
fi
1
2
3
4
5
6
7

set -u 下可用 ${optional:-} 访问可选参数。全局 IFS=$'\n\t' 只改变分词规则,也会改变 $* 的连接行为;局部 IFS= read -r、变量引用及 NUL 分隔才是针对输入的处理方式。tr ... /dev/urandom | head -c N 可能因上游 SIGPIPE 返回 141;有限输入实现见 随机串函数。

# 调试与验证

命令 检查范围
bash -n script.sh 仅检查语法,不执行;使用目标 Bash 版本
shellcheck script.sh 静态检查引用、分词等问题,需另行安装
bash -x script.sh / set -x、set +x 执行并记录展开后的命令;日志可能包含凭据,不将原始日志直接公开
trap 'printf "line=%s status=%s\n" "$LINENO" "$?" >&2' ERR 辅助定位,ERR 与 -e 有相似例外;函数继承需考虑 set -E
printf '%s\n' "${PIPESTATUS[@]}" Bash 管道各段状态,必须紧接管道;后续命令会覆盖它

先用临时目录验证正常、空输入、空格/换行文件名、目标冲突和故障状态。用模拟命令测试复制失败,避免触碰真实配置。作业控制属于当前交互 Shell,非交互脚本默认没有同样的控制终端/作业设置。

依据:Bash set 规则 (opens new window)、Bash 管道 (opens new window)。

#Shell#guide
上次更新: 2026/10/26, 22:32:55
Shell 执行模型与环境加载
Shell 常用命令速查手册

← Shell 执行模型与环境加载 Shell 常用命令速查手册→

最近更新
01
Shell 执行模型与环境加载
10-26
02
diff 与 patch:比较文件、目录和处理补丁
10-26
03
网络工具与诊断:macOS 和 Linux 对照
10-26
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式