上面命令的解释

上面命令的解释

当处于子进程中时,如何通过某些信号或 PID 的终止来退出父进程的正确 bash 命令/指令?

答案1

如果我理解正确,那么一个可能的解决方案是trap使用 shell 进程或命令。

解决方案1

笔记:使用trap它似乎只有在使用 shell 时才有用。例如,如果您在终端中运行命令或在脚本中运行 shell 代码(如myscript.sh),您将能够使用trap.

让我们看一个例子:

输入ps -fH我当前的父进程(一个zshshell),我得到:

%> ps -fH
#Output:
UID        PID  PPID  C STIME TTY          TIME CMD
edgar    17932 24608  0 23:37 pts/2    00:00:00 /bin/zsh
edgar    18001 17932  0 23:38 pts/2    00:00:00   ps -fH

现在我将运行一个bash子进程并ps -H再次输入:

%> bash
(bash shell) %> ps -fH
#Output:
UID        PID  PPID  C STIME TTY          TIME CMD
edgar    17932 24608  0 23:37 pts/2    00:00:00 /bin/zsh
edgar    18012 17932  0 23:38 pts/2    00:00:00   bash
edgar    18030 18012  0 23:38 pts/2    00:00:00     ps -fH

正如您所看到的,bash shell 的父进程带有zshPID 17932

要获取某个进程的 PPID,您应该使用ps -o ppid= $SOME_PID.例如,如果你想获取当前bash进程的父进程 ID,你应该使用:

(bash shell) %> ps -o ppid= 18012
#Output:
17932

或者还有什么更值得推荐的:

(bash shell) %> ps -o ppid= $$
#Output
17932

$$我们正在获取当前正在运行的进程的进程 ID,在本例中为bash

最后,如果您想终止父进程(zsh在本例中),您应该运行以下命令:

(bash shell) %> trap "echo Killing parent process $(ps -o ppid= $$); kill -9 $(ps -o ppid= $$)" 0 
#Or
(bash shell) %> trap "kill -9 $(ps -o ppid= $$)" 0

现在,当您键入exit或按下时,Ctrl + D父进程zsh也将被终止:

(bash shell) %> exit
#zsh was killed too, so the terminal will show the following output:
Warning: Program '/bin/zsh' crashed

为了避免zsh 崩溃了消息你可以运行两次bashshell

解决方案2

使用该strace命令应该适用于任何进程。
让我们看一个例子:

我们将在后台运行一个进程,并将strace该进程附加到可以杀死该进程的父进程。
首先,我将在shellbash中执行zsh

(zsh shell) %> bash

现在,在bashshell 中,我们将在后台运行一个进程,对于本例,我们将使用该sleep命令并获取它的 PPID(父进程 ID)。

(bash shell) %> sleep 60& #sleep 1 minute (in background)
processID=$! #with $! we get the pid of the last executed process, in this case the sleep command
parentID=$(ps -o ppid= $processID) 

如果我们查看ps -fH输出,我们会得到如下结果:

UID        PID  PPID  C STIME TTY          TIME CMD
edgar    21593 21579  0 00:43 pts/1    00:00:00 /bin/zsh
edgar    22971 21593  0 01:03 pts/1    00:00:00   bash
edgar    23011 22971  0 01:07 pts/1    00:00:00     sleep 60
edgar    23012 22971  0 01:08 pts/1    00:00:00     ps -fH

现在我们要bashsleep 60完成后杀死父进程。为此,我们将使用以下strace -p命令:

strace -p $processID ; kill -9 $parentID

strace -p 用于使用其 PID 附加进程。

当进程$processID(睡眠命令)完成时,kill 命令将运行并杀死 $parentID(bash shell)。

笔记:我不确定是否可以strace在收到信号时执行命令。此方法仅在进程完成后才有效。

上面命令的解释

ps的使用

根据ps --help

-f -- 完整列表
--forest -H -- 显示进程层次结构

ps -f与仅使用相比,输出将显示更多列ps。我曾经ps -f了解PPID每个过程。

With ps -H(您也可以使用ps --forest) 如帮助所述将显示进程层次结构,即某个进程的每个子进程将以特殊格式显示。运行ps -H我得到:

PID TTY          TIME CMD
 2872 pts/1    00:00:00 zsh
 3771 pts/1    00:00:00   bash
 7259 pts/1    00:00:00     ps

您可以看到这ps是 的子进程bash,而这是 的进程zsh

您还可以运行ps f(这是 BSD 语法)而不是ps -H

%> ps f
#Output:
PID TTY      STAT   TIME COMMAND
 2872 pts/1    Ss     0:00 /bin/zsh
 3771 pts/1    S      0:00  \_ bash
 7495 pts/1    R+     0:00      \_ ps f

陷阱的使用

的语法trap是:trap 'commands' SIGNAL.这意味着当进程接收到特定信息时,SIGNAL它将执行commands.您可以输入man trap以获得更好的描述:

条件可以是 EXIT、0(相当于 EXIT)或使用符号名称指定的信号(不带 SIG 前缀),如基本定义卷中定义的 <signal.h> 标头中的信号名称表中所列。 POSIX.1‐2017。
...
符合 XSI 的系统还允许在与以下信号名称对应的条件下使用数字信号编号:
1 SIGHUP
2 SIGINT
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM

所以如果你使用trap 'commands' 0shell,'commands'退出shell时就会执行trap中指定的内容。

例如,echoSIGINTbash shell 接收到以下代码时,将执行以下代码:

(bash_shell) %> echo Bash PID: $$
#Output:
Bash PID: 8529
(bash_shell) %> trap 'echo Bash got SIGINT signal' 2
(bash_shell) %> kill -SIGINT 8529
#Output:
^CBash got SIGINT signal

您也可以在 bash shell 中kill -SIGINT 8529按: 。Ctrl+C

笔记:用于trap某些信号可能不起作用(我已经使用 SIGKILL 进行了测试,但它不起作用)。

使用杀戮

您可以使用man killman 1p kill来获取有关该命令的更详细说明。

Kill -s 信号名 pid

Kill -l [退出状态]

杀死[-signal_name] pid

Kill [-signal_number] pid ...

-s signal_name
使用 <signal.h> 标头中定义的符号名称之一指定要发送的信号。 signal_name 的值应以与大小写无关的方式进行识别,没有 SIG 前缀。另外,应识别符号名称0,表示信号值零。应发送相应的信号而不是 SIGTERM。

-signal_name
相当于 -s signal_name。

-signal_number
指定一个非负十进制整数 signal_number,表示要使用的信号,而不是 SIGTERM,作为对kill() 的有效调用中的 sig 参数。整数值和所使用的 sig 值之间的对应关系如下表所示。指定除下列之外的任何 signal_number 的效果未定义。

0 0
1 SIGHUP
2 SIGINT
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM

所以命令kill -9 8990与 相同kill -SIGKILL 8990。发送SIGKILL到一个进程将杀死/完成这个进程。

相关内容