困惑为什么 pgrep 无法显示在 subshel​​l 中启动的作业的子级

困惑为什么 pgrep 无法显示在 subshel​​l 中启动的作业的子级

我需要使用 korn shell 来编写我正在编写的脚本,并遇到了管理嵌套子进程的问题。下面的示例代码演示了我的问题。我在其中创建了一个临时文件 x 秒,然后将其删除,以便我可以查看作业是否仍在实际运行。我得到了后台子 shell“驱动程序脚本”内部和外部的 PIDS 列表;在内部,pgrep可以找到子进程,但在外部调用时却找不到,即使两者都显示正确的父进程 PID。我不明白什么?jobs -pr如果 pgrep 不起作用,如何保证从子 shell 外部仅获取正在运行的作业的 PID(在 bash 中)?

#!/bin/ksh

# create a file for x seconds and then remove it
testfunc() {
    timesec=$1
    touch "${HOME}/testfunc/testfunc_${timesec}.file"
    sleep $timesec && rm -f "${HOME}/testfunc/testfunc_${timesec}.file"
}

# subshell to manage jobs
(

    driver_script_pid="$(exec sh -c 'echo $PPID')"

    for num in 10 35 40 5; do
        testfunc $num &
        echo "child id: $!"
    done

    echo "\$\$ $$"
    echo "subshell: $driver_script_pid"
    echo "children of parent: $(pgrep -P $$)"
    echo "children of subshell: $(pgrep -P $driver_script_pid | tr "\n" " ")"

    for ids in $(jobs -p ); do
        echo "pid: $ids PPID: $(ps -p "$ids" -o ppid=) DONE"
    done

) &

driver_pid=$!

# we still have 10 sec, 35 sec, and 40 sec job still running as verified by the files 
# existing
sleep  6
echo after 6 seconds
echo "spawned driver pid: \"$driver_pid\""
echo child processes:
echo "$(pgrep -P "$driver_pid" | tr "\n" " ")"

这是输出。 “spawned driver pid”与“subshel​​l pid”匹配,但在后台进程之外运行时,完全相同的 pgrep 会显示为空白。但是,第 10、35 和 45 秒作业的相应文件仍然存在,并在适当的时间后被删除,因此我知道作业正在运行。

child id: 27195
child id: 27196
child id: 27197
child id: 27199
$$ 27192
subshell: 27193
children of parent: 27193
children of subshell: 27195 27196 27197 27199 27205 
pid: 27199 PPID: 27193 DONE
pid: 27197 PPID: 27193 DONE
pid: 27196 PPID: 27193 DONE
pid: 27195 PPID: 27193 DONE
after 6 seconds
spawned driver pid: "27193"
child processes:

答案1

我的问题与 pgrep 无关。问题是驱动程序脚本在子级之前结束,因此所有关联都被取消引用。向驱动程序添加等待解决了我的问题。

相关内容