POSIX 終了トラップ

POSIX 終了トラップ

POSIXと互換性があるように変更しようとするBashで書かれたスクリプトがあります。 Bashのように、killall、CTRL + Cを使用してプロセスを終了したり、端末を閉じたときにEXITトラップを実行できないことを除いて、すべての操作を実行できました。これが私の出口トラップです。

#!/bin/sh

TMP=$(mktemp /tmp/countdown.XXXXX)
trap 'rm -rf $TMP' EXIT

答え1

厳密なPOSIXシェルでは、実行またはスクリプトの最後のコマンドの実行によってEXITシェルが終了する前にトラップが評価されます。exitシグナルによりシェルがシャットダウンした場合、実行されません。

をつかむには(「割り込み」信号)をCtrl+Cつかむ必要があります。INT端末を閉じるとHUP(「電話を切る」)、信号がスクリプトに送信される場合は、その信号もキャッチする必要があります。

trap 'rm -rf "$TMP"; trap - EXIT; exit' EXIT INT HUP

TERMデフォルトでは、送信される一般的な「終了」信号をキャプチャすることもできますkill

上記のトラップは、EXITトラップが呼び出されないように明示的にリセットします。再びリストされたシグナルの1つを受信して​​スクリプトが終了した場合。

答え2

Kusalanandaが述べたように、EXITPOSIXの信号は捕捉されません。最も簡単な解決策は、コードに次のようなものを追加することです。

trap exit INT HUP TERM

その後、目的の信号をキャプチャし、終了ステートメントに到達すると元のトラップを呼び出します。

答え3

一時ファイルが作成されるとすぐに削除し、ファイル記述子を介して読み書きします。

これをパスが必要なコマンドに、/dev/fd/[fd]またはコマンドに渡します。/proc/self/fd/[fd]

例:

t=$(mktemp); exec 5<>"$t"; rm "$t"

echo some text >&5
exec 5<>/dev/fd/5   # rewind / seek back at the start of the file
cat <&5

cmd1 /dev/fd/5  # cmd1 only takes paths
cmd2 5>&-       # don't leak fd 5 to cmd2

一時ファイルを複数開くこともできます分離.fdのようなexec 5<"$t" 6>"$t"

巻き戻しトリックはLinuxでのみ機能します。移植可能な方法はありません。 ;-\

関連情報