如何创建进程树?

如何创建进程树?

我有一些代码可以杀死进程及其子进程/孙进程。我想测试这段代码。

目前我正在做$ watch date > date.txt,它创建了一个带有孩子的进程。

有什么办法可以创建一个父->子->孙子树?什么命令可以实现这一点?

答案1

#!/bin/sh
#This is a process with an id of $$

( sleep 1000 )&               #this creates an idle child
( (sleep 1000)& sleep 1000 )& #this creates an idle child and grandchild
wait                          #this waits for direct children to finish

在我的系统上运行上述命令./1.sh &创建了以下进程树:

$ command ps -o pid,ppid,pgrp,stat,args,wchan --forest
  PID  PPID  PGRP STAT COMMAND                     WCHAN
24949  4783 24949 Ss   /bin/bash                   wait
25153 24949 25153 S     \_ /bin/sh ./1.sh          sigsuspend
25155 25153 25153 S     |   \_ sleep 1000          hrtimer_nanosleep
25156 25153 25153 S     |   \_ sleep 1000          hrtimer_nanosleep
25158 25156 25153 S     |       \_ sleep 1000      hrtimer_nanosleep

您可以注意到树具有相同的进程组(PGRP)的25153,这与PID第一个过程的。每当您以交互模式(或显式打开作业控制)启动新命令时,shell 都会创建一个进程组。

PGRP机制允许 shell 立即向整个进程组发送信号,而不会创建竞争条件。这用于作业控制,当您的脚本运行和前台作业时,用于发送:

  • (特别兴趣小组)INTR 当用户按下 CC
  • (特别兴趣小组)辞职 当用户按 C-\
  • (特别兴趣小组)直通车当用户按下 CZ

您可以通过执行相同的操作,例如:

kill -INTR -25153 

在哪里INTR是信号,25153 是要将信号发送到的进程组。-25153 之前的表示您的目标是PGRPid 而不是PID

就您而言,您应该发送的信号是-TERM(请求终止)。术语是默认的信号kill发送,但是,如果您的目标是一个组而不是一个,则必须明确指定它PID

kill -TERM -25153

如果你想杀死你最后启动的后台作业的进程组,你可以这样做:

kill -TERM -$!

答案2

添加 shell 调用

sh -c "watch date > date.txt"

要获得更多级别,请在周围添加更多外壳

答案3

您可以创建递归脚本。例如在文件中/tmp/run

#!/bin/bash
depth=${1:-3}
f(){
 let depth--
 if [ $depth -gt 0 ]
 then $0 $depth
 else sleep 999
 fi
}
f

然后chmod +x /tmp/run/tmp/run 3

答案4

freebsd 上的命令ps似乎无法生成进程树。幸运的是,有一个名为的包pstree,其中包含一个可以精确执行此操作的程序。

相关内容