私の python スクリプトは、シグナルプロセスモジュールで SIGINT シグナルをインターセプトして早期終了を防ぎますが、このシグナルは Popen で開いたサブプロセスに渡されます。このシグナルをサブプロセスに渡さないようにして、ユーザーが ctrl-c を押したときに途中で終了しないようにする方法はありますか?
4991 次
3 に答える
15
サブプロセスを開始するとシグナルハンドラーが継承されるため、シグナルモジュールを使用してSIGINT(signal.signal(signal.SIGINT, signal.SIG_IGN)
)を無視すると、子プロセスも自動的に継承されます。
ただし、2つの重要な注意事項があります。
- 子プロセスを生成する前に、無視ハンドラーを設定する必要があります
- 子プロセスはそれを実行するためのハンドラーコードにアクセスできないため、カスタムシグナルハンドラーはデフォルトのハンドラーにリセットされます。
したがって、SIGINTの処理を単に無視するのではなくカスタマイズする必要がある場合は、子プロセスを生成するときにSIGINTを一時的に無視してから、カスタムシグナルハンドラーを(再)設定することをお勧めします。
SIGINTをキャッチしてフラグを設定し、すぐにではなく安全なポイントで終了できるようにする場合は、その安全なポイントに到達したときに、子プロセスと開始するプロセスはSIGINTを無視します。
于 2010-09-17T00:42:51.837 に答える
2
tty
モジュールを使用してctrl-cの役割を再割り当てできます。これにより、信号の割り当てを操作できます。ただし、変更する前の状態に戻さない限り、プログラムが終了した後でも、シェルのセッション全体にわたって保持されることに注意してください。
これは、古いtty設定を保存し、ctrl-cをctrl-xに再割り当てし、終了時に以前のtty設定を復元する簡単なコードスニペットです。
import sys
import tty
# Back up previous tty settings
stdin_fileno = sys.stdin.fileno()
old_ttyattr = tty.tcgetattr(stdin_fileno)
try:
print 'Reassigning ctrl-c to ctrl-x'
# Enter raw mode on local tty
tty.setraw(stdin_fileno)
raw_ta = tty.tcgetattr(stdin_fileno)
raw_ta[tty.LFLAG] |= tty.ISIG
raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR
# ^X is the new ^C, set this to 0 to disable it entirely
raw_ta[tty.CC][tty.VINTR] = '\x18'
# Set raw tty as active tty
tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta)
# Dummy program loop
import time
for _ in range(5):
print 'doing stuff'
time.sleep(1)
finally:
print 'Resetting ctrl-c'
# Restore previous tty no matter what
tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)
于 2010-07-12T22:52:51.893 に答える