终止嵌入在 tmux 状态栏中的无限循环脚本

终止嵌入在 tmux 状态栏中的无限循环脚本

while在 tmux 状态栏中嵌入了一个无限循环 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 +++

但由于无限循环,子 shell 保持不变:

$ 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

问题

我希望子 shell 在 tmux 会话结束后自动终止。有没有办法通过更改 tmux 设置或处理SIGTERM发送到进程来做到这一点sh -c

编辑:tmux版本是2.8)

答案1

是的,开始的子进程tmux -c "start process here"似乎在相应的tmux会话中存活下来。我仔细研究了tmux广泛的手册页,有一段时间我希望在全球范围内设置tmux命令的后钩可以有所帮助。后钩具有以下形式:

 $ tmux set-hook -g after-session-closed your_cmd_here

在哪里“你的cmd_在这里”可以用来杀死生成无限循环的子进程。但这并没有帮助,因为“你的cmd_在这里”事实上必须是一个tmuxcmd而不是linux shell cmd。

相反,一个快速的技巧是在脚本的无限循环内添加一行 /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但不作为主进程的情况,即不在 的输出行的位置 4 中ps -e,而是作为正在运行的进程的参数,或者随意作为嵌入在的输出\ps -e
  • 请注意我如何使用纯粹的形式,ps在 cmd 之前添加反斜杠 as \ps。这是为了防止 cmd 的修改版本与awk.例如,如果您使用的 \ps -eF\ps -eexample,则需要更改$4$11.

HTH。

相关内容