我有一些代码可以杀死进程及其子进程/孙进程。我想测试这段代码。
目前我正在做$ 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
,其中包含一个可以精确执行此操作的程序。