从 bash 脚本启动一个新的进程组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30758424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
starting a new process group from bash script
提问by Thirupathi Thangavel
I basically want to run a script (which calls more scripts) in a new process group so that I can send signal to all the processes called by the script.
我基本上想在新的进程组中运行一个脚本(调用更多脚本),以便我可以向脚本调用的所有进程发送信号。
In Linux, I found out setsid helps me in doing that, but this is not available on FreeBSD.
在 Linux 中,我发现 setid 可以帮助我做到这一点,但在 FreeBSD 上不可用。
Syntax for setsid (provided by util-linux-ng).
setsid 的语法(由 util-linux-ng 提供)。
setsid /path/to/myscript
I, however learnt that session and process group are not the same. But starting a new session also solves my problem.
然而,我了解到会话和进程组不一样。但是开始一个新的会话也解决了我的问题。
回答by Filipe Gon?alves
Sessions and groups are not the same thing. Let's make things clean:
会话和组不是一回事。让我们把事情弄干净:
A session consists of one or more process groups, and can have a controlling terminal. When the session has a controlling terminal, the session has, at any moment, exactly one foreground process group and one or more background process groups. In such a scenario, all terminal-generated signals and input is seen by every process in the foreground process group.
一个会话由一个或多个进程组组成,并且可以有一个控制终端。当会话有一个控制终端时,该会话在任何时候都有一个前台进程组和一个或多个后台进程组。在这种情况下,前台进程组中的每个进程都可以看到所有终端生成的信号和输入。
Also, when a session has a controlling terminal, the shell process is usually the session leader, dictating which process group is the foreground process group (implicitly making the other groups background process groups). Processes in a group are usually put there by a linear pipeline. For example, ls -l | grep a | sort
will typically create a new process group where ls
, grep
and sort
live.
此外,当会话具有控制终端时,shell 进程通常是会话领导者,决定哪个进程组是前台进程组(暗示其他组成为后台进程组)。组中的进程通常通过线性管道放置在那里。例如,ls -l | grep a | sort
通常会创建一个新的过程,其中组ls
,grep
并sort
现场。
Shells that support job control (which also requires support by the kernel and the terminal driver), as in the case of bash, create a new process group for each command invoked -- and if you invoke it to run in the background (with the &
notation), that process group is not given the control of the terminal, and the shell makes it a background process group (and the foreground process group remains the shell).
支持作业控制的 Shell(也需要内核和终端驱动程序的支持),就像 bash 一样,为每个调用的命令创建一个新的进程组——如果你调用它在后台运行(使用&
表示法),该进程组未获得终端的控制权,并且外壳将其设为后台进程组(而前台进程组仍然是外壳)。
So, as you can see, you almost certainly don't want to create a session in this case. A typical situation where you'd want to create a session is if you were daemonizing a process, but other than that, there is usually not much use in creating a new session.
因此,如您所见,您几乎肯定不想在这种情况下创建会话。您想要创建会话的典型情况是,如果您正在守护进程,但除此之外,创建新会话通常没有太大用处。
You can run the script as a background job, as I mentioned, this will create a new process group. Since fork()
inherits the process group ID, every process executed by the script will be in the same group. For example, consider this simple script:
您可以将脚本作为后台作业运行,正如我所提到的,这将创建一个新的进程组。由于fork()
继承了进程组ID,脚本执行的每个进程都会在同一个组中。例如,考虑这个简单的脚本:
#!/bin/bash
ps -o pid,ppid,pgid,comm | grep ".*"
This prints something like:
这会打印如下内容:
PID PPID PGID COMMAND
11888 11885 11888 bash
12343 11888 12343 execute.sh
12344 12343 12343 ps
12345 12343 12343 grep
As you can see, execute.sh
, ps
and grep
are all on the same process group (the value in PGID
).
正如你所看到的,execute.sh
,ps
并且grep
都在同一进程群(中值PGID
)。
So all you want is:
所以你想要的只是:
/path/to/myscript &
Then you can check the process group ID of myscript
with ps -o pid,ppid,pgid,comm | grep myscript
. To send a signal to the group, send it to the group leader (PGID
is the PID
of the leader of the group). A signal sent to a group is delivered to every process in that group.
然后你可以检查myscript
with的进程组 ID ps -o pid,ppid,pgid,comm | grep myscript
。要向组发送信号,请将其发送给组长(PGID
是PID
组长的 )。发送到组的信号会传递到该组中的每个进程。
回答by taroj
Using FreeBSD you may try using the script
command that will internally execute the setsid
command.
使用 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
回答by DenisKolodin
This is not exactly answer, but is an alternative approach based on names.
这不是确切的答案,而是基于名称的替代方法。
You can have a common part of name for all process. For example we have my_proc_group_29387172part for all the following processes:
您可以为所有进程使用名称的公共部分。例如,我们有my_proc_group_29387172部分用于以下所有进程:
-rwxrwxr-x. my_proc_group_29387172_microservice_1
-rwxrwxr-x. my_proc_group_29387172_microservice_2
-rwxrwxr-x. my_proc_group_29387172_data_dumper
Spawn all of them (and as much as you want):
生成所有这些(以及您想要的数量):
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
When you want to kill all processes you can use pkillcommand (pattern kill) or killallwith --regexp parameter:
当您想杀死所有进程时,您可以使用pkill命令(模式杀死)或带有--regexp参数的killall:
pkill my_proc_group_29387172
Benefit :)- you can start as many process as you want at any time (or any day) from any script.
好处 :)- 您可以在任何时间(或任何一天)从任何脚本启动任意数量的进程。
Drawback :(- you can kill innocent processes if they has common part of name with your pattern.
缺点 :(- 如果无辜的进程与您的模式具有共同的名称部分,您可以杀死无辜的进程。