AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 568847
Accepted
Alexander Mills
Alexander Mills
Asked: 2020-02-21 20:06:07 +0800 CST2020-02-21 20:06:07 +0800 CST 2020-02-21 20:06:07 +0800 CST

tmux kill-window 不会杀死子进程

  • 772

如果我这样做ctrl-c并且ctrl-d杀死窗格中的 procs 然后从 tmux 退出,那么所有子进程都会死掉。

但如果我这样做:

ctrl+b后跟shift+%

然后选择 Y 杀死窗口,然后 procs 保持活动状态。知道如何确保窗口被杀死时触发被杀死吗?

tmux
  • 2 2 个回答
  • 1747 Views

2 个回答

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2020-02-22T04:16:28+08:002020-02-22T04:16:28+08:00

    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 或 SIGHUP;
    • 它是否以及如何对 SIGINT 或 SIGHUP 做出反应取决于进程。

    发送 SIGINT

    进程可能会忽略 SIGINT。如果Ctrl+c为您正在处理的进程执行您想要的操作,那么在杀死窗口并发送 SIGHUP 之前向它们发送 SIGINT 就足够了;好像您在每个窗格中都按了Ctrl+ 。c

    以下命令在当前窗口的窗格中列出进程(tmux 服务器的直接子进程),获取相应的前台进程组并向每个进程发送 SIGINT:

    tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{}
    

    问题是这个管道也会收到 SIGINT 并且它可能会过早终止。为了处理这个

    • 从其他地方运行命令并用于-t指定一个窗口,
    • 或者实现一些逻辑,所以排除管道的前台进程组,
    • 或在后台运行管道:

      tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{} &
      
    • 或使命令忽略信号:

      sh -c '
      trap "" SIGINT
      tmux list-panes -F "#{pane_pid}" | xargs ps -o tpgid= | xargs -I{} kill -s SIGINT -{}
      '
      

    我认为这种方法很容易出现竞争条件;事情可能会在ps和之间发生变化kill。更好的(?)替代方法是将Ctrl+发送c到每个窗格:

    tmux list-panes -F "#{pane_id}" | xargs -I {} tmux send-keys -t {} C-c &
    

    钩

    使用这个钩子让 tmux 向即将被编辑的窗口中的每个窗格发送Ctrl+ :ckill-window

    tmux set-hook before-kill-window 'run-shell "
       tmux list-panes -t \"#{window_id}\" -F \"##{pane_id}\" | xargs -I {} tmux send-keys -t {} C-c
    "'
    

    这看起来很糟糕,因为有三个级别的引用,但它似乎在我的测试中仍然有效(虽然我还没有彻底测试过)。的目的##是推迟#{pane_id}. 关键是工作#{window_id}时需要扩展run-shell,但必须生存并且仅在生成输出#{pane_id}时才扩展。list-panes

    注意钩盖kill-window但不是kill-pane,kill-session或kill-server。也不kill-window只是重复几次,所以当一个窗格被强行破坏时,钩子肯定不会 涵盖所有情况。还有和命令。kill-panebefore-kill-panerespawn-pane -krespawn-window -k


    如果不够怎么办?

    进程可能不会因 SIGINT 而终止。作为tmux list-panes -F "#{pane_pid}"起点,您可以尝试获取您想要发送 SIGTERM(甚至 SIGKILL)的 PI​​D(和/或 PGID)列表。这种通用方法的主要问题是它可能产生一个进程并完全断开它与它的祖先和 tty 的连接。

    因此,通常您可能无法跟踪源自给定 tmux 窗口的所有进程。

    • 4
  2. Nicholas Marriott
    2020-02-22T00:08:37+08:002020-02-22T00:08:37+08:00

    你没有提供足够的信息。

    C-b %拆分窗口,它不会杀死任何东西,因此您必须更改键绑定。你有什么绑定的?还是你的意思C-b &?

    杀死窗格将关闭 pty,并且内核将向任何以 pty 作为控制终端的进程发送 SIGHUP 信号,这应该使它们退出,除非它们忽略它。

    你到底在窗格中运行什么?进程根本不退出还是变成僵尸?

    了解您使用的 tmux 版本也很有帮助。

    • 1

相关问题

  • 在 tmux 会话中启动另一个脚本的 bash 脚本

  • 是否可以在不连接的情况下将输入发送到 tmux 会话?

  • tmux 和控制序列字符问题

  • Bash - 从用户那里获取输入并在 tmux 中发送具有该输入的命令

  • 从 tmux 会话回显某些内容到基础会话

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve