首页 > 解决方案 > 获取子进程的pid

问题描述

我有一个像这样的脚本:

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

child1我在其中为另一个进程运行后台进程:child2使用,child2完成后,我 kill child1.

现在无论出于何种原因,我现在想child1.sh在一个子进程中运行,即像这样运行它:

(sh child1.sh)

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

我试过了:

(sh child1.sh &)

(sh child1.sh ) &

但似乎两者都不起作用。

标签: bashpid

解决方案


从评论中,我猜您正在寻找杀死“正确”外壳的方法:

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

如果您不费心混合 child1 的 stdout 和 stderr 输出。

编辑:但我想最好杀死 child1 的子进程。如果您已/proc安装,则可以这样做:

EDIT2:获取所有孩子的 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 的子进程应该被杀死。

EDIT3:如果您的ps客户支持格式化输出,一种更简单、更安全的方法可以避免sedsort然后是:

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

推荐阅读