set -euo pipefail,以及只有它还不够的原因
一句话总结
严格模式用于阻止脚本悄悄产生错误结果,但它不能自动解决清理、并发执行和重试问题。
安全结构
未定义变量、管道前段失败和错误命令应尽早终止;同时收紧 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