web-dev-qa-db-ja.com

シェルスクリプト内でNohupジョブが完了するのを待つにはどうすればよいですか?

次のスクリプトがあります。

echo "$wk" | while read -r a b;
do
    counter=$(($counter+1))
    Nohup sh -c 'impala-Shell -d nielsen -f query.sql --var=dt=$a --var=incre=$b;
    echo $a,$?>>$week_status_file;
    if [ $? -ne 0 ]; then
        echo $a,$b>>$err_week_file
    fi'
    if [ $(($counter%5)) == 0 -a $counter -ge 5 ];
    then
        echo "Check"
        wait
    fi
done

アイデアは、ラップされたコマンドimpala-Shell...を2つの変数ab(変数wkから取得)で開始することです。これは、5つのプロセスと並行して実行する必要があります。次の5つのジョブは、前の5つのプロセスが終了するまで待機する必要があります。私の現在のコードはCheckを出力しますが、まったく待機しません。ただし、waitsleep 10sに変更すると、スリープ状態になります。

ここでwaitを機能させるにはどうすればよいですか?

2
lovechillcool

プロセス識別子(PID)をwaitに指定する必要があります。また、あなたの説明から、あなたのコマンドがブロックしているようには聞こえません。それは最終的にあなたが待ちたいPIDを集めるのを難しくします。例えば。プロセスがフォークしていて、新しいフォークされたプロセスのPIDを知らなくてもスクリプトを続行できる場合。

ただし、Nohup sh -c ...行がブロックされている場合は、&を使用してバックグラウンドに送信し、バックグラウンドプロセスのPIDを保存して、最後に保存したすべてのPIDを待ちます(例:$WAIT_FOR_PIDS) 。変数$!は、バックグラウンド実行に送信された最後のプロセスのPIDを提供します。

WAIT_FOR_PIDS="";
echo "$wk" | while read -r a b;
do
    counter=$(($counter+1))
    Nohup sh -c 'impala-Shell -d nielsen -f query.sql --var=dt=$a --var=incre=$b;
    echo $a,$?>>$week_status_file;
    if [ $? -ne 0 ]; then
        echo $a,$b>>$err_week_file
    fi' & WAIT_FOR_PIDS="$WAIT_FOR_PIDS $!"
    if [ $(($counter%5)) == 0 -a $counter -ge 5 ];
    then
        echo "Check"
        wait $WAIT_FOR_PIDS
        WAIT_FOR_PIDS=""
    fi
done

また、$week_status_fileに並行してエコーしながら、競合状態を考慮する必要があります。シェルでアクセス可能なファイルロックを簡単に行うには、man flockを参照してください。

1
thomas