Bash 陷阱在函数中,但在整个脚本退出时执行?

Bash 陷阱在函数中,但在整个脚本退出时执行?

我想知道这样的事情是否可能。

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.

相关内容