web-dev-qa-db-ja.com

POSIXでトラップを終了

Bashで作成したスクリプトがあり、POSIXに準拠するように変更しようとしています。プロセスがkillall、CTRL + C、またはターミナルを閉じると終了するときにEXITトラップをトリガーできないため、Bashの場合と同様に、すべてを正常に機能させることができました。これが私の出口トラップです:

#!/bin/sh

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

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

キャッチしますか Ctrl+C、あなたはINT(「割り込み」信号)をトラップする必要があります。ターミナルを閉じると、スクリプトにHUP( "hang-up")信号が送信される場合は、それもトラップする必要があります。

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

TERM、デフォルトでkillによって送信される一般的な「終了」信号をトラップすることもできます。

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

4
Kusalananda

一時ファイルを作成した直後に削除し、ファイル記述子を介して一時ファイルを読み書きします。

パスが必要なコマンドに/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

exec 5<"$t" 6>"$t"のように、一時ファイルを複数のseparate fdsとして開くこともできます。

巻き戻しのトリックはLinuxのみです。私はそれを行うためのポータブルな方法を考えることはできません。アイデアは大歓迎です;-\

0
pizdelect