考虑这个脚本,它调用一个函数,并为该函数设置trap
a RETURN
:
#!/usr/bin/env bash
set -euo pipefail
function f1() {
local temp_file
temp_file="$(mktemp)"
trap 'echo DELETED; rm -- "${temp_file}"' RETURN
date > temp_file
}
function main() {
for i in $(seq 0 2); do
f1
done
}
main
由于某种原因,这会打印DELETED
字符串 4 次(而不是 3 次)并失败并出现unbound variable
错误:
DELETED
DELETED
DELETED
DELETED
hack/deploy-example-server.sh: line 13: temp_file: unbound variable
显然,有什么东西导致了 this 的额外执行trap
,我怀疑这是整个脚本的退出。
function main
如果我消除,并且仅f1
在顶级脚本中调用 for 循环,则不会发生这种情况。
是什么导致了这种行为?
答案1
您设置的任何内容trap
都是全局的。
第四个陷阱发生在main()
返回时。此时,该local
变量temp_file
不再被设置。 (因此出现unbound variable
错误。)
main()
考虑在循环之后取消陷阱for
。我认为你可以用 解除陷阱trap RETURN
。
或者(最好?),考虑使用trap
.
选项 1:将要删除的每个文件附加到数组中,然后稍后显式删除这些文件。
选项2:f1()
用另一个函数包装函数f2()
,并f2()
删除文件。也许像下面这样(我没有测试过):
#! /usr/bin/env bash
set -euo pipefail
function trace() {
# usage: trace command [arg ...]
echo "+ $*" 1>&2
"$@"
}
function f1() {
true # replace true with your code
}
function f2() {
# usage: f2 func_name
local func_name="$1"
local temp_file="$(mktemp)"
"$func_name"
trace rm -- "$temp_file"
}
function main() {
for i in $(seq 0 2); do
f2 f1
done
}
main