且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从 bash 脚本启动一个新的进程组

更新时间:2023-12-05 13:47:10

会话和组不是一回事.让我们把事情弄干净:

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.

另外,当一个会话有一个控制终端时,shell 进程通常是会话领导者,决定哪个进程组是前台进程组(隐式地让其他组成为后台进程组).组中的进程通常通过线性管道放置在那里.例如,ls -l |grep 一个 |sort 通常会创建一个新的进程组,其中 lsgrepsort 存在.

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.

支持作业控制的外壳(也需要内核和终端驱动程序的支持),如在 bash 的情况下,为每个调用的命令创建一个新的进程组——如果你调用它在后台运行(使用 & 表示法),该进程组未获得终端的控制权,shell 将其设为后台进程组(而前台进程组仍为 shell).

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).

因此,如您所见,您几乎肯定不想在这种情况下创建会话.您想要创建会话的典型情况是,如果您正在守护进程,但除此之外,创建新会话通常没有太大用处.

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.

您可以将脚本作为后台作业运行,正如我所提到的,这将创建一个新的进程组.由于 fork() 继承了进程组 ID,脚本执行的每个进程都将在同一个组中.例如,考虑这个简单的脚本:

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:

#!/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).

As you can see, execute.sh, ps and grep are all on the same process group (the value in PGID).

所以你想要的是:

/path/to/myscript &

然后你可以用ps -o pid,ppid,pgid,comm | 查看myscript的进程组ID |grep myscript.要向组发送信号,请将其发送给组长(PGID 是组长的 PID).发送到组的信号会传递到该组中的每个进程.

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.