SIGTSTP、SIGTTIN、およびSIGTTOUの「トラップコマンド」をオーバーライドできません。

SIGTSTP、SIGTTIN、およびSIGTTOUの「トラップコマンド」をオーバーライドできません。

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回入力ZCtrl+ C):

$ ./signal.sh
trap -- 'echo TSTP' SIGTSTP
trap -- 'echo TTIN' SIGTTIN
trap -- 'echo TTOU' SIGTTOU
^ZTSTP
^ZTSTP
^ZTSTP
^C

私が見つけたマニュアルにBashがインタラクティブで、ジョブ制御が有効になっている場合は、次の信号を無視します。

  1. ジョブ制御はデフォルトで有効になっています(ジョブ制御を参照)。ジョブ制御が適用されると、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に置き換えて、他のプロセスを確認できます。

関連情報