我有一个这样的脚本:
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 ) &
但两者似乎都不起作用。
从评论中,我想你是在寻找杀死"右";外壳:
child=$(
sh "child1.sh" 1>&2 &
echo $! )
echo "main pid $child"
sh child2.sh
kill "$child"
如果您不想混淆child1的stdout和stderr输出。
编辑:但我想最好杀死child1的子进程。如果安装了/proc
,则可以执行此操作:
EDIT2:按顺序获取所有子项的PID,以便显示,请注意,kill
将向每个PID发送SIGTERM
,而不必为顺序而烦恼。并处理cmd名称中带有括号或空格的进程。
child=$(
sh "child1.sh" 1>&2 &
echo $! )
echo "main pid $child"
sh child2.sh
child_proc=$(cat /proc/*/stat | sed 's/([^)]*)*( [TRS])/proc1/' | 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的子进程。
EDIT3:如果您的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