2011-11-08 58 views
6

我写了一个脚本从平行的HDFS获取数据,然后我在for循环中等待这些子进程,但有时它返回“pid不是这个壳的孩子“。有时候,它运作良好。它很困惑。我使用“jobs -l”来显示所有在后台运行的作业。我确定这些pid是shell进程的子进程,我使用“ps aux”来确保这些pid是note分配给其他进程。这是我的脚本。等待子进程,但得到错误:'pid不是这个shell的孩子'

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 

回答

2

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

编辑如果while循环或循环实际上是这件事会发生

(a)在{...}块 (二)参与吹笛(如for....done|somepipe

+0

无论是我把这些循环在{...}块,也不使用....完成| somepipe。 – henshao

+0

尽管如此,您仍然可以检查这一思路。在两个位置(并在脚本的顶级位置打印$ BASHPID,$$,$ BASH_SUBSHELL) – sehe

11

只要找到进程您想要等待的进程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

+0

智能技巧!人们可以这样等待,然后在过程完成后启动脚本。 – Viet

+0

不太好,如果每个计算机程序都使用这样的轮询,这将是一件非常糟糕的事情:) –