
次のbashスクリプトがあります。
##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done
別の30個のループを続行するために、最初のforループの後に別のforループを作成したいと思います。例えば
##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
for i in {31..60}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done
新しいタスクを開始する前に、最初のタスクを終了したいと思います。しかし、nohup
彼らはすべて同時に実行されているようです。
nohup
私は私のサーバーにTelnetを接続し、そこで作業を開始してから私のbashを閉じるので、それを持っています。代替ソリューションはありますか?
答え1
wait
これを行うには、このコマンドを使用する必要があります。すべての子プロセスIDをキャプチャして具体的に待つことができます。あるいは、スクリプトが生成する唯一のバックグラウンドプロセスである場合は、引数なしでwait
直接呼び出すこともできます。たとえば、
#!/bin/bash
# run two processes in the background and wait for them to finish
nohup sleep 3 &
nohup sleep 10 &
echo "This will wait until both are done"
date
wait
date
echo "Done"
答え2
今数時間:
nohup
リモートシェルのシャットダウンによるワーカープロセスの終了を防ぐことが目的である場合は、スクリプトが生成するnohup
個々のワーカープロセスではなくスクリプト自体で使用する必要があります。説明どおりここ、
nohup
プロセスがSIGHUPを受信して端末と対話するのを防ぐだけで、シェルとその子プロセスとの間の関係を失うことはありません。上記のために、2つのループ間に簡単な操作があるかどうかにかかわらず、最初の
nohup
ループで開始されたすべての子プロセスが終了した後にのみ2番目のループが実行されます。wait
for
for
for
簡単なものを使用してください
wait
:現在アクティブなすべての子プロセスを待ち、状態0を返します。
for
最初の項目にエラーがない場合にのみ2番目の項目を実行する必要がある場合は、各ワーカープロセスPIDを保存し、$!
すべて次に渡す必要がありますwait
。pids= for ... worker ... & pids+=" $!" done wait $pids || { echo "there were errors" >&2; exit 1; }
答え3
2つのループの間に次の内容を挿入するとfor
便利です。
flag=0
while [ flag -eq 0 ]
do
ps -ef | grep "Rscript --vanilla" | grep -v grep > /dev/null
flag=${?}
sleep 10
done
もちろん、アプリケーションがRscript
正常に完了せずに中断される可能性がある場合は、2番目のforループが実行されない可能性があります。上記のコードスニペットは、対応する識別子を持つすべてのプロセスがRscript --vanilla
正しく完了して消えることを前提としています。あなたのアプリケーションが何をしているのか、どのように機能するのかわからないので、私はこの仮定に頼る必要があります。
編集する
レビューによると、このオプションはお客様のニーズに適している可能性があります。 (オリジナルコードと完了確認ロジックが含まれています)
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
pids[$i]=${!}
done
flag=0
while [ flag -eq 0 ]
do
for PID in $(echo ${pids[@]})
do
flag=1
ps -ef | grep ${PID} | grep -v grep >/dev/null; r=${?}
if [ ${r} -eq 0 ]
then
flag=0
fi
done
done
for i in {31..60}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done