Tmuxステータスバーに無限のwhile
ループbashスクリプトが埋め込まれています。 〜/ .tmux/conf内:
set -g status-right '... #(path/loop.sh) ...'
Tmuxはこのスクリプトをsh -c
で実行しているようです。 tmuxの開始後:
$ ps x | grep loop.sh
23433 pts/4 S+ 0:00 grep --color=auto loop.sh
31814 ? S 0:00 sh -c path/loop.sh
31818 ? S 0:00 /bin/bash path/loop.sh
tmux kill-session
は、sh -c
プロセスを終了します。 strace
してセッションを強制終了した場合:
$ strace -p 31814
strace: Process 31814 attached
wait4(-1, 0x7ffeacbfbf9c, 0, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=27643, si_uid=1000} ---
+++ killed by SIGTERM +++
しかし、無限ループのため、サブシェルは変更されません。
$ ps x | grep loop.sh
2443 pts/4 S+ 0:00 grep --color=auto loop.sh
31818 ? S 0:00 /bin/bash path/loop.sh
質問
Tmuxセッションの終了後にサブシェルを自動的に終了させたいのですが。 tmux設定を変更するか、sh -c
プロセスに送信されたSIGTERM
を処理することで、これを行う方法はありますか?
(編集:tmuxのバージョンは2.8です)
はい、tmux -c "start process here"
で開始された子プロセスは、対応するtmux
セッションを生き延びているようです。私はtmux
'の広範なマニュアルページを詳しく調べており、しばらくの間、tmux
コマンドのアフターフックをグローバルに設定することが役立つことを望んでいました。アフターフックの形式は次のとおりです。
$ tmux set-hook -g after-session-closed your_cmd_here
ここで"your_cmd_here"は、無限ループを生成する子プロセスを強制終了するために使用された可能性があります。ただし、"your_cmd_here"は実際にはLinuxシェルコマンドではなくtmux
コマンドである必要があるため、この方法では役に立ちません。
代わりに、簡単なハックは、/path/loop.sh
スクリプトの無限ループ内に次のような行を追加することです。
[ "x$(ps -e | grep tmux | grep -v grep)" = "x" ] && break
これにより、tmux
がps -ae
の出力にアクティブなプロセスを表示しなくなるとすぐに、無限ループから抜け出します。逆に、tmux
関連のプロセスが表示された場合、ループは影響を受けずに続行されます。
実際には、上記のテストのより良いバージョンです。tmux
セッションを終了するコーナーケースですが、たとえば、システムでアクティブなman tmux
プロセスは次のとおりです。
[ $(\ps -e | awk 'BEGIN {rv=0}; tolower($0) ~/tmux/ {if ($4 == "tmux") {rv=1}; exit} END {print rv}') == "1" ] && break
tmux
が\ps -e
の出力に表示されるが、メインプロセスとしては表示されない場合、つまりps -e
の出力行の位置4ではなく、実行中のプロセス、または\ps -e
の出力に埋め込まれた(サブ)文字列として何気なく。\ps
としてバックスラッシュを追加することにより、純粋な形式のps
をどのように使用したかに注意してください。これは、cmdの変更されたバージョンがawk
の位置パラメーター番号を混乱させるのを防ぐためです。例えば。たとえば、\ps -eF
の代わりに\ps -e
を使用した場合は、$4
を$11
に変更する必要があります。HTH。