私はインタラクティブなPython CLIツールを書いています。特定の信号が発生したときに、このツールを「特殊テキスト入力モード」にしたいと思っています。私は現在、SIGINTを正しく処理して正常に終了します。PythonでSIGINT以外の信号をキャッチ
質問:私は、このモードを入力するために使用する必要がありますどのような信号
- ? (他の機能を妨げないもの)
- この信号を捕捉する最良の方法は何ですか?
- この信号はどのようにPOSIXシステムでトリガされますか? Windowsでは違うの?
私はインタラクティブなPython CLIツールを書いています。特定の信号が発生したときに、このツールを「特殊テキスト入力モード」にしたいと思っています。私は現在、SIGINTを正しく処理して正常に終了します。PythonでSIGINT以外の信号をキャッチ
質問:私は、このモードを入力するために使用する必要がありますどのような信号
はPOSIXは、指定丁度2つのユーザ定義の信号:これらの2つの信号はあなたが明示的にこれらのハンドラを定義し、あなたの目的のために、これらの信号を上げることができることを意味し、任意のアクションによってトリガーされていない
SIGUSR1 = 30
SIGUSR2 = 31
。
import signal
def handler(signum):
if signum == signal.SIGUSR1:
print('user defined interrupt!')
signal.signal(signal.SIGUSR1, handler)
これらの信号は、ユーザーの目的に応じて明示的に提供されているため、アプリケーションでこれらの信号を発生させて処理することをお勧めします。
明示的にコードでこの信号を上げるために、あなたが使用する必要があります:
os.getpid()
は、現在のプロセスのプロセスIDを返す
import os
os.kill(os.getpid(), signal.SIGUSR1)
。これを、現在のプロセスでない場合は、削除するプロセスのIDに置き換えます。
また、SIGUSR1/2
はWindowsではサポートされていません。文書には、SIGABRT
,SIGFPE
,SIGILL
,SIGINT
,SIGSEGV
、またはSIGTERM
の他に、他の信号を発生させることはできないことが記載されています。それ以外の場合はValueErrorが発生します。
signal
を標準ライブラリから使用する必要があります。 Hereがその一例です。 は一般的には、すなわち、特定のシグナルハンドラを指定:
import signal
import time
import sys
def handler(signum, frame):
print(signum, frame)
sys.exit(1)
signal.signal(signal.SIGINT, handler)
while True:
time.sleep(1)
ですから、Ccのキーを押したときに終了しない場合は、handler
は、信号数と引数として現在のスタックフレーム(で実行されますそこでは、プログラムはその実行を継続する)。あなたは同じ方法で他のシグナルを捕まえることができます(signal.SIGHUPなど)。 たとえば、ユーザが予約した信号を処理するには、端末からsignal.signal(signal.SIGUSR1, handler)
、次にkill -USR1 <pid>
を使用できます。
ありがとう! SIGUSR1をCTRLシーケンスのようにトリガする方法はありますか?または、インタラクティブなCLIアプリケーションの内部から? – Princey
'psutil'を使ってプロセスを' Process'オブジェクトとして取得し、 'send_signal'を呼び出します([docs](http://pythonhosted.org/psutil/#psutil.Process .send_signal)を実行してください)。制御シーケンスに関しては、bashスクリプトでトラップを使用する方法を示す[this](http://www.linuxquestions.org/questions/linux-general-1/sigusr1-from-keyboard-511146/)のリンクが見つかりました。 – alexpeits
これはまさにそれです!ありがとうございました!私は、CTRLシーケンスが実際にこれらをトリガするものを見つけることができないようです...彼らが何であるか知っていますか? – Princey
ああ...すみません。私は言及すべきだった。これを明示的にraiseする必要があります: 'os.kill(os.getpid()、signal.SIGUSR1)'(または中断したいプロセス)。 SIGINTとSIGKILLに加えて、他のシグナル(私が信じる)のどれもキーボード割り込みではありません - それらは唯一の2つです。 –
@Princey:手動でシグナルを発生させてプロセスを中断させる実行可能な停止条件を見つけなければなりません。うーん、これはあなたが発明的になることができる場所です:) –