次のスクリプトがあります。
#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat # wait indefinitely
SIGHUP
(使用)を送信するとkill -HUP pid
何も起こりません。
スクリプトを少し変更すると、次のようになります。
#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT # add this
trap "echo HUP" SIGHUP
cat # wait indefinitely
...これにより、echo HUP
終了時にスクリプトが正しく機能します(Ctrl + Cを押したとき)。
roger@roger-pc:~ $ ./hupper.sh
We are 6233
^CHUP
どうなりますか?SIGHUP
このスクリプトにシグナルを送信するにはどうすればよいですか(必ずしもそうではありません)。
答え1
答え2
@xhienneが理由を説明しました。ただし、信号がすぐに機能するようにするには(スクリプトを終了するのではなく)、コードを次のように変更できます。
#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP
{ cat <&3 3<&- & pid=$!; } 3<&0
while
wait "$pid"
ret=$?
"$interrupted"
do
interrupted=false
done
exit "$ret"
ファイル記述子を使用する小さな方法は、stdinがバックグラウンドで開始されたコマンドbash
にリダイレクトされることを避けることです。/dev/null
答え3
EXITにトラップがあると、スクリプトは信号を受信したときに外部コマンドが終了するのを待たないことに気づきました。スクリプト例:
$ cat test-trap
#!/bin/bash
echo "We are $$"
trap "echo 'Trapping EXIT'" EXIT
cat
実行してください:
$ ./test-trap
We are 24814
送信:
$ ./test-trap
We are 24814
# Doing `kill -HUP 24814` in another terminal
Trapping EXIT
Hangup
しかし、混乱した放棄された猫がいるかもしれません。
cat: -: Input/output error
この問題を解決するには、トラップによって呼び出された関数から子プロセスを検索して終了する必要があります。
Ctrl+を押すC:
$ ./test-trap
We are 24814
^CTrapping EXIT
Ctrl+のD代わりにCtrl+を押すと、Ccatコマンドは正常に終了します。ただし、スクリプトが終了するとトラップが実行されます。
$ ./test-trap
We are 40183
# I pressed Ctrl+D here...
Trapping EXIT
スクリプトの最後でトラップを取り消すことでこれを防ぐことができます。
#!/bin/bash
echo "We are $$"
trap "echo 'Trapping EXIT'" EXIT
cat
trap - EXIT
EXITをキャッチするさまざまな動作に関するドキュメントが見つかりません。たぶん他の人もそうすることはできませんか?