我有一个像这样的脚本:
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 ) &
但似乎都不起作用。
从评论中,我猜你正在寻找它来杀死“正确的”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
这里的关键是,当你创建一个子进程时,你得到的PID是子进程的shell的。 所以,你要做的就是使用
pkill -P
杀死子 shell 的所有子进程:
(sh child1.sh) &
child=$!
sh child2.sh
pkill -P "$child"