获取子进程的pid

问题描述 投票:0回答:2

我有一个像这样的脚本:

sh child1.sh &
child=$!
sh child2.sh
kill "$child"

我为其他进程运行后台进程

child1
:使用
child2
,当
child2
完成时,我杀死
child1

现在无论出于何种原因,我现在想在子进程中运行

child1.sh
,即像这样运行它:

(sh child1.sh)

如何将子进程的 id 传递给父进程,以便我可以像以前一样杀死它?

我尝试过:

(sh child1.sh &)

(sh child1.sh ) &

但似乎都不起作用。

bash pid
2个回答
1
投票

从评论中,我猜你正在寻找它来杀死“正确的”shell:

child=$(
sh "child1.sh" 1>&2 &
echo $! )
echo "main pid $child"
sh child2.sh
kill "$child"

如果您不愿意混合 child1 的 stdout 和 stderr 输出。

编辑:但我想最好杀死child1的子进程。如果您安装了

/proc
,您就可以做到这一点:

编辑2:获取所有孩子的PID按顺序用于显示,请注意,

kill
将向每个孩子发送
SIGTERM
并且不必理会顺序。并处理 cmd 名称中带有括号或空格的进程。

child=$(
sh "child1.sh" 1>&2 &
echo $! )
echo "main pid $child"
sh child2.sh
child_proc=$(cat /proc/*/stat | sed 's/([^\)]*)*\( [TRS]\)/proc\1/' | sort -k4n,1n | awk -v parent=${child} -F' '  '
BEGIN {pids[0]=parent;}
{fnd=-1;for(i=0;i<=npids;i++) { if (pids[i]==$4) fnd=i; }
 if (fnd!=-1) { pids[npids++]=$1;;}
}
END { for(i=npids-1; i>=0; i--) print pids[i]; }')
echo "childs of child1 : $child_proc"
kill $child_proc

child1 和 child2 shell 都会正常退出,只有 child1 的子进程应该被杀死。

编辑3:如果您的

ps
客户端支持格式化输出,那么避免
sed
sort
的更简单、更安全的方法将是:

child=$(
sh "child1.sh" 1>&2 &
echo $! )
echo "main pid $child"
sh child2.sh
child_proc=$(ps -o pid= -o ppid= -A | awk -v parent=${child} -F' '  '
BEGIN {pids[0]=parent;}
{fnd=-1;for(i=0;i<=npids;i++) { if (pids[i]==$2) fnd=i; }
 if (fnd!=-1) { pids[npids++]=$1;;}
}
END { for(i=npids-1; i>=0; i--) print pids[i]; }')
echo "childs of child1 : $child_proc"
kill $child_proc

0
投票

这里的关键是,当你创建一个子进程时,你得到的PID是子进程的shell的。 所以,你要做的就是使用

pkill -P
杀死子 shell 的所有子进程:

(sh child1.sh) &
child=$!
sh child2.sh
pkill -P "$child"
© www.soinside.com 2019 - 2024. All rights reserved.