如果我这样做ctrl-c并且ctrl-d杀死窗格中的 procs 然后从 tmux 退出,那么所有子进程都会死掉。
但如果我这样做:
ctrl+b后跟shift+%
然后选择 Y 杀死窗口,然后 procs 保持活动状态。知道如何确保窗口被杀死时触发被杀死吗?
如果我这样做ctrl-c并且ctrl-d杀死窗格中的 procs 然后从 tmux 退出,那么所有子进程都会死掉。
但如果我这样做:
ctrl+b后跟shift+%
然后选择 Y 杀死窗口,然后 procs 保持活动状态。知道如何确保窗口被杀死时触发被杀死吗?
Ctrl+c对比
kill-window
使用Ctrl+c您通常(当
stty -a
显示时intr = ^C
)将 SIGINT 发送到前台进程组中的进程。您似乎假设任何获得 SIGINT 退出(被杀死)的进程,但通常它可能不会。您提到了Ctrl+ d,因此 tmux 服务器和您要终止的进程之间可能存在一个交互式 shell。在这种情况下,SIGINT 被发送到进程,而不是 shell;但即使外壳得到它,它也不会退出。(我不是说它总是这样;我是说它符合你的描述)。
因此,似乎在进程终止于Ctrl+之后c,您点击Ctrl+d退出 shell。
当您在 tmux 中杀死一个窗口时,相应的伪终端将关闭,并且使用它们作为控制终端的进程会收到 SIGHUP。然后,这样的进程可能会向其子进程发送 SIGHUP(对于 shell,请参阅此答案)。进程可能会忽略该信号(请参阅 参考资料
nohup
)。即使它忽略了信号,如果它试图使用一个不再存在的伪终端,它也可能(或可能不会)在以后死亡。简而言之:
发送 SIGINT
进程可能会忽略 SIGINT。如果Ctrl+c为您正在处理的进程执行您想要的操作,那么在杀死窗口并发送 SIGHUP 之前向它们发送 SIGINT 就足够了;好像您在每个窗格中都按了Ctrl+ 。c
以下命令在当前窗口的窗格中列出进程(tmux 服务器的直接子进程),获取相应的前台进程组并向每个进程发送 SIGINT:
问题是这个管道也会收到 SIGINT 并且它可能会过早终止。为了处理这个
-t
指定一个窗口,或在后台运行管道:
或使命令忽略信号:
我认为这种方法很容易出现竞争条件;事情可能会在
ps
和之间发生变化kill
。更好的(?)替代方法是将Ctrl+发送c到每个窗格:钩
使用这个钩子让 tmux 向即将被编辑的窗口中的每个窗格发送Ctrl+ :c
kill-window
这看起来很糟糕,因为有三个级别的引用,但它似乎在我的测试中仍然有效(虽然我还没有彻底测试过)。的目的
##
是推迟#{pane_id}
. 关键是工作#{window_id}
时需要扩展run-shell
,但必须生存并且仅在生成输出#{pane_id}
时才扩展。list-panes
注意钩盖
kill-window
但不是kill-pane
,kill-session
或kill-server
。也不kill-window
只是重复几次,所以当一个窗格被强行破坏时,钩子肯定不会 涵盖所有情况。还有和命令。kill-pane
before-kill-pane
respawn-pane -k
respawn-window -k
如果不够怎么办?
进程可能不会因 SIGINT 而终止。作为
tmux list-panes -F "#{pane_pid}"
起点,您可以尝试获取您想要发送 SIGTERM(甚至 SIGKILL)的 PID(和/或 PGID)列表。这种通用方法的主要问题是它可能产生一个进程并完全断开它与它的祖先和 tty 的连接。因此,通常您可能无法跟踪源自给定 tmux 窗口的所有进程。
你没有提供足够的信息。
C-b %
拆分窗口,它不会杀死任何东西,因此您必须更改键绑定。你有什么绑定的?还是你的意思C-b &
?杀死窗格将关闭 pty,并且内核将向任何以 pty 作为控制终端的进程发送 SIGHUP 信号,这应该使它们退出,除非它们忽略它。
你到底在窗格中运行什么?进程根本不退出还是变成僵尸?
了解您使用的 tmux 版本也很有帮助。