2011-11-08 61 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

不太好,如果每個計算機程序都使用這樣的輪詢,這將是一件非常糟糕的事情:) –