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が述べたように、EXIT
POSIXの信号は捕捉されません。最も簡単な解決策は、コードに次のようなものを追加することです。
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でのみ機能します。移植可能な方法はありません。 ;-\