SIGTSTP信号をキャプチャしたいのですが、できません。trap
引数なしでコマンドを呼び出すと、次の結果が表示されます。
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
明らかに、鉱山には事前trap
定義された動作があります。問題は、rootとしてログインしても無視できないことです。このコマンドを使用すると、trap
これら3つの信号は無視されます。そうでなければうまくいきます。
次のコマンドで書き直しました。
trap -- 'echo SIGTSTP' SIGTSTP
もう一つの奇妙なことは、これらの信号が利用可能で正しく動作し、無視されないことです。単にSIGTSTPを使用して他のプロセスの操作を停止し、SIGCONTを使用して再び続行することができます。
それでは、このコマンドを書き換える方法を知っていますか?この奇妙な行動を説明できますか?
私のオペレーティングシステムはLubuntu 15.04で、GNU bashバージョン4.3.30(1)リリース(x86_64-pc-linux-gnu)を使用しています。
答え1
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
セッション例(Ctrl+ 3回入力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
。しかし、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
答え2
どのシェルを使用しているのか言及していないので、これがシェルのバグであれば助けることはできません。
Bourne Shell のマニュアルページをご覧ください。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
したがって、すべてが大丈夫かもしれませんが、シェルはこれらのシグナルを無視して呼び出されます。
最新のオペレーティングシステムを使用している場合は、次を呼び出すことができます。
`psig $$`
現在のシェルのシグナルハンドラを取得します。 $$を別のプロセスIDに置き換えて、他のプロセスを確認できます。