2011-11-08 33 views
6

Tôi viết một kịch bản để lấy dữ liệu từ HDFS song song , sau đó tôi chờ đợi các quá trình con trong vòng lặp for, nhưng đôi khi nó trả về "pid không phải là một đứa trẻ của vỏ này ". đôi khi, nó hoạt động tốt. Nó rất bối rối. Tôi sử dụng "jobs -l" để hiển thị tất cả các công việc đang chạy trong nền. Tôi chắc chắn những pid là quá trình con của quá trình vỏ, và tôi sử dụng "ps aux" để đảm bảo rằng các pids là lưu ý gán cho quá trình khác. Đây là kịch bản của tôi.chờ đợi quá trình con nhưng nhận được lỗi: 'pid không phải là một đứa trẻ của vỏ này'

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 

Trả lời

2

Vòng lặp while hoặc vòng lặp for chạy trong một vỏ con, đó là lý do tại sao bạn không thể đợi con của vỏ (mẹ, bên ngoài).

Sửa điều này có thể xảy ra nếu vòng lặp while hoặc vòng lặp for thực sự là

(a) trong một khối {...} (b) tham gia vào một người thổi sáo (ví dụ for....done|somepipe)

+0

Cả tôi đặt những vòng trong {...} khối, và cũng không sử dụng cho .... làm | somepipe. – henshao

+0

Bạn có thể kiểm tra dòng suy nghĩ này, tuy nhiên, ví dụ: in $ BASHPID, $$, $ BASH_SUBSHELL ở cả hai vị trí (và ở mức to lớn của tập lệnh của bạn!) – sehe

11

Chỉ cần tìm quá trình id của quá trình bạn muốn đợi và thay thế bằng 12345 trong tập lệnh bên dưới. Các thay đổi khác có thể được thực hiện theo yêu cầu của bạn.

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

Mẹo thông minh! Người ta có thể chờ đợi như thế này và sau đó khởi chạy kịch bản sau khi quá trình kết thúc. – Viet

+0

không tốt như vậy, nếu mỗi chương trình máy tính sử dụng bỏ phiếu như thế này, nó sẽ là một điều rất xấu :) –

Các vấn đề liên quan