等待子进程但出现错误:“pid 不是此 shell 的子进程”

问题描述 投票:0回答:3

我写了一个脚本从 HDFS 并行获取数据,然后我在一个 for 循环中等待这些子进程,但有时它返回

pid is not a child of this shell
。有时,它运作良好。真是百思不得其解。我使用
jobs -l
来显示后台运行的所有作业。我确定这些 pid 是 shell 进程的子进程,并且我使用
ps aux
来确保这些 pid 被注意分配给其他进程。这是我的脚本。

PID=()
FILE=()
let serial=0

while read index_tar
do
        echo $index_tar | grep index > /dev/null 2>&1

        if [[ $? -ne 0 ]]
        then
                continue
        fi

        suffix=`printf '%03d' $serial`
        mkdir input/output_$suffix
        $HADOOP_HOME/bin/hadoop fs -cat $index_tar | tar zxf - -C input/output_$suffix \
                && mv input/output_$suffix/index_* input/output_$suffix/index &

        PID[$serial]=$!
        FILE[$serial]=$index_tar

        let serial++

done < file.list

for((i=0;i<$serial;i++))
do
        wait ${PID[$i]}

        if [[ $? -ne 0 ]]
        then
                LOG "get ${FILE[$i]} failed, PID:${PID[$i]}"
                exit -1
        else
                LOG "get ${FILE[$i]} success, PID:${PID[$i]}"
        fi
done
linux shell wait
3个回答
31
投票

只需找到您要等待的进程的进程 ID,并在下面的脚本中将其替换为 12345。可以根据您的要求进行进一步的更改。

#!/bin/sh
PID=12345
while [ -e /proc/$PID ]
do
    echo "Process: $PID is still running" >> /home/parv/waitAndRun.log
    sleep .6
done
echo "Process $PID has finished" >> /home/parv/waitAndRun.log

/usr/bin/waitingScript.sh

http://iamparv.blogspot.in/2013/10/unix-wait-for-running-process-not-child.html


7
投票

您的 while 循环或 for 循环在子 shell 中运行,这就是为什么您不能等待(父,外部)shell 的子级。

编辑 如果 while 循环或 for 循环实际上是

(a) 在

{...}
块中 (b) 参与吹笛(例如
for....done|somepipe


5
投票

如果您在某种容器中运行它,则该情况显然可能是由 bash 中的错误引起的,该错误在容器化环境中更容易遇到

根据我对 bash 源 的阅读(具体请参阅

RECYCLES_PIDS
CHILD_MAX
中的评论),看起来他们在努力优化对后台作业的跟踪,他们让自己容易受到 PID 别名的影响(新流程可能掩盖旧流程的状态);为了缓解这种情况,他们修剪了他们的后台进程历史(显然是 POSIX 强制要求的?)。如果您碰巧想要
bash-4.2/jobs.c
修剪过的进程,shell 无法在历史记录中找到它,并假定这意味着它从来不知道它(即它“不是这个 shell 的子进程”) ).
    

© www.soinside.com 2019 - 2024. All rights reserved.