unix 从bash脚本启动新进程组

xt0899hw  于 2023-05-22  发布在  Unix
关注(0)|答案(3)|浏览(195)

我基本上想在一个新的进程组中运行一个脚本(它调用更多的脚本),这样我就可以向脚本调用的所有进程发送信号。
在Linux中,我发现setsid可以帮助我做到这一点,但这在FreeBSD上不可用。
setsid的语法(由util-linux-ng提供)。

setsid /path/to/myscript

然而,我了解到会话和进程组是不一样的。但是开始一个新的会话也解决了我的问题。

xriantvc

xriantvc1#

会议和小组不是一回事。让我们把事情弄清楚:
一个会话由一个或多个进程组组成,可以有一个控制终端。当会话具有控制终端时,会话在任何时刻都具有恰好一个前台进程组和一个或多个后台进程组。在这种情况下,前台进程组中的每个进程都可以看到所有终端生成的信号和输入。
此外,当会话具有控制终端时, shell 进程通常是会话领导者,指示哪个进程组是前台进程组(隐含地使其他组成为后台进程组)。组中的进程通常通过线性管道放置在那里。例如,ls -l | grep a | sort通常会创建一个新的进程组,其中存在lsgrepsort
支持作业控制的Shell(这也需要内核和终端驱动程序的支持),就像bash的情况一样,为每个被调用的命令创建一个新的进程组--如果您调用它是为了在后台运行(用&表示法),该进程组不被给予终端的控制,并且 shell 使其成为后台进程组(并且前台进程组仍然是 shell )。
因此,正如您所看到的,在这种情况下,您几乎肯定不想创建会话。创建会话的一个典型情况是,您正在守护进程,但除此之外,创建新会话通常没有太多用处。
您可以将该脚本作为后台作业运行,正如我提到的,这将创建一个新的进程组。由于fork()继承了进程组ID,因此脚本执行的每个进程都将位于同一个组中。例如,考虑这个简单的脚本:

#!/bin/bash

ps -o pid,ppid,pgid,comm | grep ".*"

这将打印如下内容:

PID  PPID  PGID COMMAND
11888 11885 11888 bash
12343 11888 12343 execute.sh
12344 12343 12343 ps
12345 12343 12343 grep

正如您所看到的,execute.shpsgrep都在同一个进程组(PGID中的值)上。
所以你想要的是:

/path/to/myscript &

然后您可以使用ps -o pid,ppid,pgid,comm | grep myscript检查myscript的进程组ID。要向组发送信号,请使用kill和进程组ID的 * 负数 *(PGID是组领导者的PID)。发送到一个组的信号被传递到该组中的每个进程。在上面的示例中,要将SIGTERM发送到由execute.sh启动的每个进程,包括脚本本身,您将使用kill -- -12343。(注意,向整个组发送信号不同于仅向组长发送信号:kill 12343kill -- -12343是不同的!)

b09cbbtk

b09cbbtk2#

在FreeBSD中,你可以尝试使用script命令,它将在内部执行setsid命令。

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null /path/to/myscript
stty echo onlcr
# sync  # ... if terminal prompt does not return
ycl3bljg

ycl3bljg3#

这不是确切的答案,而是基于名称的替代方法。
您可以为所有进程提供一个公共的名称部分。例如,我们为以下所有进程设置了my_proc_group_29387172part:

-rwxrwxr-x.   my_proc_group_29387172_microservice_1
-rwxrwxr-x.   my_proc_group_29387172_microservice_2
-rwxrwxr-x.   my_proc_group_29387172_data_dumper

生成所有这些(以及您想要的数量):

ADDR=1 ./my_proc_group_29387172_microservice_1
ADDR=2 ./my_proc_group_29387172_microservice_1
ADDR=3 ./my_proc_group_29387172_microservice_2
./my_proc_group_29387172_data_dumper

当你想杀死所有进程时,可以使用pkill命令(模式kill)或killall并带**--regexp**参数:

pkill my_proc_group_29387172

好处:)-您可以在任何时间(或任何一天)从任何脚本启动任意多个进程。
缺点:(-如果进程的名字与你的模式有共同的部分,你可以杀死它们。

相关问题