juechafun/05-原子化笔记本/Linux-set处理未定义和错误.md

3.0 KiB
Raw Blame History


#领域/Linux

#复盘/1

一句话描述

[_set退出脚本]


核心规范

空想不如行动,积累胜于苛求。 实践 > 沉淀 > 完美主义

实践不是盲目行动,而是带着“小目标、可验证“的方向试错,实践后必须沉淀(比如记录问题、总结规律),否则就是低水平重复。

实践大于沉淀,沉淀大于完美;完美是沉淀的终局方向,沉淀是实践的复盘产物;分域施策,避坑落地,始于行动,终于迭代。


三省沉淀法

  • 达成了[脚本基础异常时退出执行____]目标
  • 遇到了[并未覆盖所有异常____]问题
  • 下次改进[整理手动处理规范____]

个人理解

[set -euo pipefail 标准用法,覆盖未定义、遇到错误,并接收第一个失败错误码____]

实践计划

#状态/待实践

  1. [整理手动处理异常规范____]
  2. [________]
  3. [________]

核心定义

  1. set -u 检测到 [未定义变量____] 时退出脚本
  2. set -e 检测到 [遇到错误] 时退出脚本
  3. set -o pipefail 接收 [第一个失败命令的错误码]

生产环境标配: 开启严格模式:覆盖变量、命令、管道三类错误检测

set -euo pipefail

示例

示例一set -u 未定义变量

#!/bin/bash
# 未开启set -u未定义变量被当作空值
echo "未开启-u$undefined_var"  # 输出"未开启-u",脚本继续
echo "脚本执行到这里(未开启-u"

# 开启set -u未定义变量直接报错
set -u
echo "开启-u$undefined_var"    # 报错line 8: undefined_var: unbound variable
echo "脚本不会执行到这里(开启-u"  # 不会执行

示例二set -e 遇到错误

#!/bin/bash
# 未开启set -e命令失败仍继续执行
ls /不存在的目录  # 报错No such file or directory
echo "脚本执行到这里(未开启-e"  # 仍会执行

# 开启set -e命令失败直接退出
set -e
ls /不存在的目录  # 报错后脚本退出
echo "脚本不会执行到这里(开启-e"  # 不会执行

避坑点

⚠️ 避坑点1set -e 部分场景失效 核心问题set -e 不会捕获 if cmd ; then、cmd || true、未开pipefail的错误 解决方案: 手动检查配合set -o pipefail

if ls /不存在的目录; then
    echo "成功"
else
    err_code=$?
    echo "失败,错误码:$err_code"
    exit $err_code
fi
ls /不存在的目录 | echo # 这里管道结果为 0 不会报错

# 需要配合 -o pipefail 来获取管道第一个错误来退出

⚠️ 避坑点2set -u 对参数变量误判 核心问题set -u 下, bash特性不会对 $*$@ 报错 解决方案: 使用参数前先判断数量

if [ $# -lt 1 ]; then
    echo "请传入参数!"
    exit 1
fi
echo "第一个参数:$1"

⚠️ 避坑点3pipefail 不直接导致脚本退出 核心问题pipefail 仅修改管道错误码,需搭配 set -e 解决方案: pipefail 必须搭配 set -e