2011-11-08 12 views
6

Scrivo uno script per ottenere dati da HDFS in parallelo, quindi attendo questi processi secondari in un ciclo for, ma a volte restituisce "pid non è un bambino di questo guscio ". a volte funziona bene. È così perplesso. Io uso "jobs -l" per mostrare tutti i lavori eseguiti in background. Sono sicuro che questi pid sono il processo figlio del processo di shell, e io uso "ps aux" per assicurarmi che questi pids vengano assegnati ad altri processi. Ecco la mia sceneggiatura.attendere processo figlio ma ottenere errore: 'pid non è figlio di questa 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 

risposta

2

O il vostro ciclo while o per ciclo viene eseguito in una subshell, motivo per cui non si può attendere un figlio del guscio (genitore, esterno).

Modifica questo potrebbe accadere se il ciclo while o per ciclo è in realtà

(a) in un blocco {...} (b) la partecipazione a un Piper (ad es for....done|somepipe)

+0

Né ho messo questi cicli in {...} blocco, nè utilizzare per .... fatto | somepipe. – henshao

+0

Puoi comunque controllare questa linea di pensiero, ad es. stampando $ BASHPID, $$, $ BASH_SUBSHELL in entrambe le posizioni (e al livello più alto del tuo script!) – sehe

11

Basta trovare il processo id del processo che si desidera attendere e sostituirlo con 12345 nello script sottostante. Ulteriori modifiche possono essere fatte secondo il vostro requisito.

#!/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

Smart trick! Si può aspettare così e quindi avviare gli script dopo che il processo è finito. – Viet

+0

non è così buono, se ogni programma di computer usato polling come questo, sarebbe una cosa molto brutta :) –

Problemi correlati