web-dev-qa-db-ja.com

子プロセスを待機しますが、エラーが発生します: 'pidはこのシェルの子ではありません'

HDFSパラレルからデータを取得するスクリプトを作成し、これらの子プロセスをforループで待機しますが、「pidはこのシェルの子ではありません」と返されることがあります。時々、それはうまくいきます。それはとても困惑しています。 「jobs-l」を使用して、バックグラウンドで実行されているすべてのジョブを表示します。これらのpidはシェルプロセスの子プロセスであると確信しています。「psaux」を使用して、これらの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
19
henshao

以下のスクリプトで、待機するプロセスのプロセス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

17
Parvinder Singh

Whileループまたはforループのいずれかがサブシェルで実行されるため、(親、外部)シェルの子を待つことはできません。

編集これはwhileループまたはforループが実際にある場合に発生する可能性があります

(a){...}ブロック(b)パイパーに参加している(例:for....done|somepipe

4
sehe

ある種のコンテナーでこれを実行している場合、条件 コンテナー化された環境で発生しやすいbashのバグが原因である可能性があります

bashソース (具体的にはRECYCLES_PIDSCHILD_MAXbash-4.2/jobs.cに関するコメントを参照)を読んだところ、バックグラウンドの追跡を最適化するための努力のようです。ジョブの場合、PIDエイリアシングに対して脆弱なままになります(新しいプロセスが古いプロセスのステータスを覆い隠す可能性があります)。それを軽減するために、彼らはバックグラウンドプロセス履歴を削除します(明らかにPOSIXによって義務付けられているように?)。削除されたプロセスでwaitしたい場合、シェルは履歴でそれを見つけることができず、これはそれについて知らなかったことを意味すると想定します(つまり、「の子ではない」このシェル」)。

0
jhfrontz