From comments, i guess you're looking for that to kill the "right" shell :
child=$(
sh "child1.sh" 1>&2 &
echo $! )
echo "main pid $child"
sh child2.sh
kill "$child"
If you don't bother to mix stdout and stderr output from child1.
EDIT: But i guess it's better to kill the child processes of child1. You can do that if you have /proc
mounted :
EDIT2: Get all the child's PIDs in order for display, note that kill
will send SIGTERM
to each of them and don't bother with order. And take care of processes with parenthesis or space(s) in cmd name.
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
Both child1 and child2 shells will exit gracefully, only sub-processes of child1 should be killed.
EDIT3: If your ps
client supports formatted output, a simpler and safer way avoiding sed
and sort
would then be :
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