私はPythonでコマンドラインユーティリティを作成しています。これは製品コードであるため、大量のもの(エラーコード、スタックトレースなど)をダンプせずにクリーンにシャットダウンできるはずです。画面。これは、キーボードの割り込みをキャッチする必要があることを意味します。
私は両方のtry catchブロックを使用してみました:
if __== '__main__':
try:
main()
except KeyboardInterrupt:
print 'Interrupted'
sys.exit(0)
そして、シグナル自体をキャッチします( this post のように):
import signal
import sys
def sigint_handler(signal, frame):
print 'Interrupted'
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
どちらの方法も、通常の操作では非常にうまく機能するようです。ただし、アプリケーションの最後のクリーンアップコード中に割り込みが発生した場合、Pythonは常に何かを画面に出力するようです。割り込みをキャッチすると、
^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored
一方、信号の処理は、
^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored
または
^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored
これらのエラーは見苦しいだけでなく、あまり役に立ちません(特にソースコードのないエンドユーザーにとって)!
このアプリケーションのクリーンアップコードはかなり大きいため、この問題が実際のユーザーにヒットする可能性はかなりあります。この出力をキャッチまたはブロックする方法はありますか、それとも私が対処しなければならないものですか?
チェックアウト このスレッド 、終了とトレースバックに関する有用な情報があります。
プログラムを強制終了するだけに興味がある場合は、次のようなものを試してください(これにより、クリーンアップコードの下でも脚が削除されます)。
if __== '__main__':
try:
main()
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(0)
except SystemExit:
os._exit(0)
シャットダウンの開始後、クリーンアップコードを開始する前にsignal.signal(signal.SIGINT, signal.SIG_IGN)
を呼び出すことにより、SIGINTを無視できます。