SIGTSTP信号をトラップしたいのですが、トラップできません。引数なしでtrap
コマンドだけを呼び出すと、次のようになります。
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
明らかに、私のtrap
にはすでに事前定義された動作がいくつかあります。問題は、rootとしてログに記録されていても、書き換えることができないことです。 trap
コマンドを使用すると、これら3つの信号では単に無視されます。それ以外の場合は正常に動作します。
次のように、コマンドだけで書き直そうとしました。
trap -- 'echo SIGTSTP' SIGTSTP
もう1つの奇妙なことは、この信号を使用でき、正常に機能していることです。無視されません。 SIGTSTPを使用して、他のプロセスの動作を停止し、SIGCONTを再度続行することができます。
それで、あなたはそれらのコマンドを書き直す方法を知っていますか?そして、この奇妙な行動を少し説明していただけませんか?
私のOSはLubuntu15.04で、GNU bash、バージョン4.3.30(1)-リリース(x86_64-pc-linux-gnu)を使用しています。
Ubuntu 15.04のbashを使用すると、期待どおりに機能するようです...スクリプトをどのように記述しますか?
#!/bin/bash
set -e
trap 'echo TSTP' TSTP
trap 'echo TTIN' TTIN
trap 'echo TTOU' TTOU
trap
while :; do read a; done # wait forever
サンプルセッション(3回入力) Ctrl+Z その後 Ctrl+C):
$ ./signal.sh
trap -- 'echo TSTP' SIGTSTP
trap -- 'echo TTIN' SIGTTIN
trap -- 'echo TTOU' SIGTTOU
^ZTSTP
^ZTSTP
^ZTSTP
^C
マニュアルで bashがインタラクティブで、ジョブ制御が有効になっている場合、これらの信号を無視することがわかりました。
- ジョブ制御(ジョブ制御を参照)はデフォルトで有効になっています。ジョブ制御が有効な場合、Bashはキーボードで生成されたジョブ制御信号SIGTTIN、SIGTTOU、およびSIGTSTPを無視します。
set +m
でジョブcotnrolを無効にできます。ただし、bashではインタラクティブモードでハンドラーを更新することはできません。
$ bash -c trap
$ bash -c 'trap true TSTP && trap'
trap -- 'true' SIGTSTP
$ bash -i -c trap
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
$ bash -i -c 'trap true TSTP && trap'
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
$ bash -i -c 'set +m && trap true TSTP && trap'
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
使用しているシェルについて言及していなかったため、これがシェルのバグである場合、支援する方法はありません。
Bourne Shellのmanページを見る: http://schillix.sourceforge.net/man/man1/bosh.1.html 次のテキストが表示されます。
bolic names. Any attempt to set a trap on a signal that
was ignored on entry to the current Shell is ineffec-
tive. An attempt to trap on signal 11 (memory fault)
produces an error.code here
したがって、すべて問題ないかもしれませんが、これらの信号を無視してシェルが呼び出されました。
最新のOSを使用している場合は、
`psig $$`
現在のシェルのシグナル処理を取得し、$$を他のプロセスIDに置き換えて、他のプロセスをチェックすることができます。