関数に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ディレクトリを作成できることを知っています。しかし、インストール/削除などの他の作業にも広く使用されているので、この方法を使いたいと思います。

どんなアイデアがありますか?よろしくお願いします。

編集:したがって、シェルスクリプトの終わりにTRAPが呼び出されますが、元の質問ではサブシェル($())を使用していました。コードを次の形式に再フォーマットした後、動作するようになりました。

#!/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が実行されます。
[...] 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

関連情報