我想知道这样的事情是否可能。
function get_temp_dir() {
local tmp_dir=$(mktemp -d)
trap "{
rm -r $tmp_dir
}" EXIT
echo $tmp_dir
}
temp=$(get_temp_dir)
# I'd like to $temp for the duration of this script, and deleted
# when this current scope ends, not when the function scope ends.
我见过其他脚本使用全局数组和单个陷阱函数来实现相同的效果,该陷阱函数枚举数组并对其执行某些操作。如果可以的话我想避免这种情况。
我还知道我可以只创建一个 tmp 目录,并在该目录中创建多个 tmp 目录。但是,我想使用这种方法,因为它广泛用于其他事情,例如安装/卸载。
有任何想法吗?提前致谢。
编辑:所以,当 shell 脚本结束时,TRAP 确实会被调用,但是,在我最初的问题中,我使用的是子 shell ( $()
)。将代码重新格式化为以下格式后,我得到了它的工作:
#!/usr/bin/env bash
function get_temp_dir() {
local tmp_dir=$(mktemp -d)
trap "{
rm -r $tmp_dir
}" EXIT
retval=$tmp_dir
}
get_temp_dir
tmp_dir=$retval
ls $tmp_dir
答案1
我认为您正在寻找RETURN
信号:
[...] 如果 SIGNAL_SPEC 为 EXIT (0) ARG 在退出 shell 时执行。
[...] 如果 SIGNAL_SPEC 为 RETURN,则每次 .shell 函数或脚本运行时都会执行 ARG。或源内置程序完成执行。
例子:
$ bash
$ trap "echo shell exiting" EXIT
$ fn() { trap "echo function exiting" RETURN; }
$ fn
function exiting
$ (fn)
function exiting
$ value=$(fn); echo "$value"
function exiting
$ exit
shell exiting
并且,与这个问题密切相关:
$ f2() {
local tmp=$(mktemp)
trap 'rm "$tmp"' RETURN
echo "$tmp"
date >> "$tmp"
cat "$tmp"
}
$ f2
/tmp/tmp.MHpI20X0a1
Fri May 11 14:29:01 EDT 2018
$ ls -l /tmp/tmp.MHpI20X0a1
ls: cannot access '/tmp/tmp.MHpI20X0a1': No such file or directory
答案2
在我的脚本中,当我要写入临时文件时,我经常在一开始就这样做:
scratch="$(mktemp -d)"
trap 'rm -fr "$scratch"' EXIT
mkdir $scratch/foo; touch $scratch/foo/bar
任何实际的文件或目录都可以在脚本过程中按名称(例如 )写入,但在脚本以trap
.