アプリケーションXがtmuxウィンドウの前景で実行されているとします。 SIGUSR1という特定の信号をアプリケーションXに送信したいと思います。現在選択されているウィンドウのフォアグラウンドプロセス(またはプロセスグループ)にシグナルを送信するようにtmuxキーバインディングを設定できますか?
答え1
私のKubuntuは、ps
プロセスが接続されている端末のフォアグラウンドプロセスグループIDを提供します。キーワードはです。で識別されたプロセスtpgid
のクエリを渡すと、このウィンドウでフォアグラウンドプロセスグループIDが取得されます。ps
tmux
#{pane_pid}
次のバインディング(in ~/.tmux.conf
)はprefixkSIGUSR1をフォアグラウンドプロセスグループ(デフォルトprefixはCtrl+ b)に送信します。
bind-key k run-shell 'kill -s USR1 -- "-$(ps -o tpgid:1= -p #{pane_pid})"'
メモ:
前のダッシュ(
-
)は$(…)
前景プロセスを見つけるのに役立ちます。グループ。ダッシュなしで試すことができ、1つのプロセスのみをターゲットにすると、そのプロセスはフォアグラウンドプロセスグループの「リーダー」になります。しかし、「リーダー」が(まだ)存在するという保証はありません。グループをターゲティングするのは合理的なアプローチであり、Ctrl+ cSIGINT をグループに送信するのと似ていますが、メカニズムは異なります。:1
この答えから抜粋:ps
スペースなしでコマンド出力形式を設定します。。前にダッシュを追加するときは、先行スペースを削除することが重要です。競争条件があります。
kill
その後実行され、ps
プロセスグループがまだフォアグラウンドにあるか、まったく存在するという保証はありません。残念ながらprefixk、ターゲットにするプロセスが終了すると問題が発生する可能性があります。誤ってSIGUSR1を他のプロセスに送ることができます。おそらく殻になるでしょう。それから…
SIGUSR1 の基本操作は終了です。。特に、フォアグラウンドにある(つまり、コマンドを待つ)インタラクティブシェルはprefixk.bashで実行できます。事前にトラップを設定してこれを防ぐことができます。
trap '' USR1
シェルはシグナルを無視します。この場合、子プロセスは明示的に信号を処理するように選択しない限り信号を無視しますdd
。trap : USR1
シェルはシグナルを「無視」(何もせずに応答)しますが、これは子プロセスの動作には影響しません。
答え2
Tmuxはこれを提供しますpane_pid
が、これは通常シェルインウィンドウで最上位プロセスのPIDになります。フォアグラウンドプロセスのPIDを見つけるにはもう少し詳しく調べる必要がありますが、それをpane_pid
開始点として使用できます。
単純なバージョン - 次のように:
bind k run-shell "kill -s SIGUSR1 $(cat /proc/#{pane_pid}/task/#{pane_pid}/children)"
ウィンドウにバックグラウンドプロセスがない場合、これはうまくいくと思います。
シェルで複数のピアプロセスが実行されていて、その一部がバックグラウンドにある場合、状況はさらに複雑になります。私はps -h --ppid #{pane_pid} -O stat
子プロセスを取得するために使用するのと同じことをpane_pid
行い、そのうちのどのプロセスが前景で実行されているかを確認し(つまり、列に+
1つあるSTAT
)、そのPIDを解析する必要があると思います。
可能な実装の1つは次のとおりです。
bind k run-shell "kill -s SIGUSR1 $(ps -h --ppid #{pane_pid} -O stat | grep -o '^[[:blank:]]*[[:digit:]]\\+[[:blank:]]\\+[^[:blank:]]*+' | cut -d ' ' -f2)"
ただし、次の場合はまだ失敗します。いいえ子プロセス(つまり、ウィンドウのフォアグラウンドプロセスはシェル自体です)。
もちろん、堅牢性をさらに一歩引き上げる必要がある場合は、シェルスクリプトに移動して実際に存在することを確認してください。はいシグナルを送信する前の子プロセスです。