LabHub
学习 学习路径 课程

Shell 脚本

set -euo pipefail,以及只有它还不够的原因

在 LabHub 中继续学习

一句话总结

严格模式用于阻止脚本悄悄产生错误结果,但它不能自动解决清理、并发执行和重试问题。

概念图: 一句话总结 · 安全结构 · 原文命令与标识符

安全结构

未定义变量、管道前段失败和错误命令应尽早终止;同时收紧 IFS,减少空格文件名造成的意外分词。errexit 在 if、逻辑运算和函数条件中有明确例外,不能单独依赖。

清理函数应先保存原退出码,再删除临时资源并恢复退出码;临时文件必须安全创建。定时任务还应使用锁避免重叠,并以不同退出码区分失败与“已有实例运行”。

网络重试必须限制次数、加入退避、成功后立即停止,并先确认操作是否幂等。ShellCheck 可在 CI 中发现引号遗漏和危险模式。命令替换、赋值与截断管道也可能掩盖失败,应显式检查。

原文命令与标识符

tar czf "$DEST" "$SRC_DIR"
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
cleanup() {
  local rc=$?
  rm -f "$TMPFILE"
  exit "$rc"
}
trap cleanup EXIT
setup() {
  mkdir -p /srv/data      # 여기서 실패해도
  cp config.yml /srv/data # 이 줄이 실행된다
}
if setup; then echo "준비 완료"; fi
VERSION=$(cat /etc/app/version)   # 파일이 없어도 스크립트는 계속 간다
VERSION=$(cat /etc/app/version) || exit 1
: "${VERSION:?버전 파일이 비어 있습니다}"
tmp=$(mktemp -d) || exit 1
trap 'rm -rf "$tmp"' EXIT

set -euo pipefail

SRC_DIR

set -u

-e

if

||

-u

-o pipefail

curl ... | jq ... | wc -l

IFS

set -e

||

if

-e

-e

-e

trap

EXIT

$?

mktemp

/tmp

flock

mkdir

set -e

set -euo pipefail

set -e

if

while

&&

||

!

if

set -e

cp

VERSION=...

cat

local

export

pipefail

set -e

curl ... | jq .

curl

jq

pipefail

head

SIGPIPE

|| true

trap

EXIT

set -e

exit

INT

TERM