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 / 问题 / 767405
Accepted
Martin Vegter
Martin Vegter
Asked: 2024-01-21 15:07:19 +0800 CST2024-01-21 15:07:19 +0800 CST 2024-01-21 15:07:19 +0800 CST

在“进程组”中启动多个终端窗口,以便在任何一个进程终止时可以杀死剩余的进程

  • 772

我有一个启动 3 个终端模拟器窗口的脚本:

#!/bin/sh

terminator --role='terminator-left' 2>/dev/null &
sleep 0.1
terminator --role='terminator-center' 2>/dev/null &
sleep 0.1
terminator --role='terminator-right' 2>/dev/null &

(我使用 --role 选项,以便我可以自动将窗口放置在不同的显示器上,在我的 openbox 配置文件中定义)

我在不同的虚拟桌面上多次启动此脚本。

如何在某种“进程组”中启动这 3 个终端,以便在其中任何一个进程终止时可以杀死所有剩余进程?

重要提示:我不想终止可能在脚本的不同实例中启动的所有终端(我不能只使用 pkill 或 pgrep 来终止与模式匹配的任何进程)

换句话说,假设我在虚拟桌面 1 和虚拟桌面 2 上启动脚本。

我现在在 2 个不同的虚拟桌面上有 3 个终端窗口。

当我退出虚拟桌面 1 上的一个终端时,我希望其余 2 个窗口自动终止,但不会影响在虚拟桌面 2 上运行的其他 3 个窗口的独立实例。

我所描述的可能吗?

我怎样才能做到这一点?

shell-script
  • 3 3 个回答
  • 110 Views

3 个回答

  • Voted
  1. Best Answer
    MC68020
    2024-01-22T21:28:55+08:002024-01-22T21:28:55+08:00

    免责声明:
    我没有机会在 openbox 下测试我的建议。我仅在 kde-plasma 下验证了它,
    我的解决方案依赖于 POSIX 程序员手册中记录的waitshell 内部命令。使用 -n 选项,某些特定的实现可以使脚本更简单。


    #!/bin/sh
    
    ownkill()
    {
            trap - CHLD
            pkill --signal 15 -P $$ 
    }
    
    terminator --role='terminator-left' 2>/dev/null &
    sleep 0.1
    terminator --role='terminator-center' 2>/dev/null &
    sleep 0.1
    terminator --role='terminator-right' 2>/dev/null &
    trap ownkill CHLD
    wait
    

    该脚本基于以下想法:

    1. 根据需要启动 3 个终止程序进程,
    2. 等待他们完成,
    3. 以终止其余进程的方式处理终止上述进程之一的 SIGCHLD 信号。

    注 1(重置处理程序):正如 aviro 在注释中正确观察到的那样,信号处理程序必须将 SIGCHLD 的处理重置为默认值,因为杀死剩余进程将触发其他(最多 2 个)SIGCHLD。
    如果不这样做,将迫使 shell 处于某种递归情况(处理程序必须处理它自己生成的信号),根据 shell 实现或多或少地进行优雅的管理。(从无害的警告到超过某些最大递归深度或等效错误。)

    注 2(保持 SIGCHLD 默认处理直到等待):正如 Martin Vegter 在注释中正确观察到的,该trap ownkill CHLD指令应紧接在等待指令之前放置。
    将其作为脚本的第一条指令(正如我在前面的版本中荒谬地建议的那样)将在第一个sleep进程终止后立即触发专用处理程序。

    • 3
  2. meuh
    2024-01-22T14:46:02+08:002024-01-22T14:46:02+08:00

    使用 bash,您可以简单地收集所有进程 id,并在最后等待,以便当任何进程退出(bash 的wait -n)时,所有 id 都会被一些合适的信号杀死:

    #!/bin/bash
    terminator --role='terminator-left' 2>/dev/null &
    pid1=$!
    sleep 0.1
    terminator --role='terminator-center' 2>/dev/null &
    pid2=$!
    sleep 0.1
    terminator --role='terminator-right' 2>/dev/null &
    pid3=$!
    wait -n
    kill -hup $pid1 $pid2 $pid3 2>/dev/null
    

    由于其中一个 pid 已经失效,我们将killstderr 重定向到 null 以避免出现错误消息。

    • 2
  3. meuh
    2024-01-21T23:46:44+08:002024-01-21T23:46:44+08:00

    您可能愿意使用 systemd 瞬态单元,因为它的启动、控制和停止都很简单。假设您的 shell 脚本是,在其末尾./myscript添加一个命令,以便它不会立即完成,那么您可以使用以下命令启动它:wait -n

    systemd-run --user --unit=mytest1 ./myscript
    

    此命令立即返回消息Running as unit: mytest1.service,您可以使用常用命令查看创建的瞬态单元中正在运行哪些进程:

    systemctl status --user mytest1
    

    您可以使用一个命令停止所有进程:

    systemctl stop --user mytest1
    

    要多次运行同一脚本,只需确保 --unit=每次使用不同的名称即可。如果它们都以 开头test,那么您可以检查它们全部,或者通过将它们引用为 来停止它们test*。

    请参阅man systemd-run了解可能有用的各种选项,例如 --setenv=、--working-directory=、--collect、--wait。请注意,您还可以在命令末尾将参数传递给脚本systemd-run。

    • 1

相关问题

  • 在awk中的两行之间减去相同的列

  • 打印文件行及其长度的脚本[关闭]

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 按分隔符拆分并连接字符串问题

  • MySQL Select with function IN () with bash array

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