önceki komutlar bitinceye kadar bash komut dosyasını duraklatma


20

Aşağıdaki gibi görünen bir bash betiği var:

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

İlki için 30 tane daha devam etmek için bir tane daha döngü oluşturmak istiyorum. Örneğin.

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

Yeni kümeye başlamadan önce ilk iş grubunun bitmesini istiyorum. Ama nohupöyle görünüyor ki hepsi aynı anda çalışıyor.

Ben var nohupçünkü uzaktan sunucuma giriş yapıp oradaki işleri başlatıyorum ve bash'ımı kapatıyorum. Alternatif bir çözüm var mı?


1
waitYerleşik için kılavuzu arayın .
Satō Katsura

Yanıtlar:


22

Bunu waitsizin için yapmak için komutu kullanmak isteyeceksiniz. Tüm alt işlem kimliklerini yakalayabilir ve özellikle bekleyebilirsiniz veya komut dosyanızın oluşturduğu tek arka plan işlemleri bunlarsa, waitbağımsız değişken olmadan arayabilirsiniz . Örneğin:

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

6

Birkaç nokta:

  • Hedefiniz, nohupuzak kabuk çıkışının çalışan işlemlerinizi öldürmesini önlemekse, nohupoluşturduğu tek çalışan işlemlerde değil, komut dosyasının kendisini kullanmalısınız .

  • Açıklandığı gibi burada , nohupsadece SIGHUP almasına ve terminal ile etkileşim süreçlerini engelleyen, ancak kabuk ve çocuk süreçler arasında bir ilişki kesilmez.

  • Yukarıdaki noktadan ötürü, olsun ya da olmasın nohup, waitiki fordöngü arasındaki bir basit , ikincisinin forancak ilk tarafından başlatılan tüm alt süreçler forçıktıktan sonra yürütülmesine neden olur .

  • Basit bir şekilde wait:

    şu anda aktif olan tüm alt süreçler beklenir ve dönüş durumu sıfırdır.

  • İkincisini foryalnızca ilkinde hata yoksa çalıştırmanız gerekiyorsa, her çalışan PID'sini ile kaydetmeniz $!ve tümünü şu adrese iletmeniz gerekir wait:

    pids=
    for ...
        worker ... &
        pids+=" $!"
    done
    wait $pids || { echo "there were errors" >&2; exit 1; }

Sunucuda çalışan başka işler olabilir. Ben sadece parti için beklemek isterdim Yani .. onlar altında çalıştırılır, böylece Ar betikleridir Rveya cc1plusiçinde topkomut
masfenix

Ayrıca "paralel" tüm komutları çalıştırmak için nohup kullanmak istiyorum. temelde bunlar bilimsel bir program için simülasyonlardır. Toplamda 180 simülasyon çalıştırmak istiyorum, ancak 60'lık gruplar halinde. Sayaç da 1'den 180'e gitmeli. Bunları teker teker yaparsam, çok uzun sürecek.
masfenix

waitbashortaya çıktığı arka plan işlerini beklemeye neden olur , başka bir şey. Burada bazı karışıklıklar olabilir - bu fordöngüler, onları bir dosyaya kaydettiniz mi ve bir komut dosyası olarak mı çağırdınız ( ##scriptsatırdan dolayı varsaydım ) veya terminalde elle mi yazıyorsunuz?
Matei David

-1

fgYerleşik kullanın . Arka plan işlemleri bitene kadar bekler.

help fgAyrıntılar için deneyin .


Bir komut dosyası iş denetimi olmadan çalışır.
Kusalananda

-1

İki fordöngünüzün arasına aşağıdaki kod segmenti gibi bir şey eklerseniz yardımcı olabilir.

flag=0

while [ flag -eq 0 ]
do
  ps -ef | grep "Rscript --vanilla" | grep -v grep > /dev/null
  flag=${?}
  sleep 10
done

Tabii ki, uygulamanızın Rscriptbaşarılı bir şekilde tamamlanma ve etrafta dolaşma şansı varsa, ikinci döngü döngünüzün çalışma şansı olmayabilir. Yukarıdaki kod segmenti, tanımlayıcıya sahip tüm işlemlerin Rscript --vanilladoğru şekilde tamamlanacağını ve kaybolacağını varsayar . Başvurunuzun ne yaptığını ve nasıl çalıştığını bilmeden, bu varsayımlara güvenmek zorundayım.

DÜZENLE

Yorumların ışığında, bu ihtiyaçlarınızı daha iyi karşılayacaktır. (orijinal kodunuzu ve tamamlama kontrol mantığını içerir)

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

İçindeki işlem adı bazen veya öğesini topgösterir . Rcc1plus
masfenix

Bu durumda, ps -eflistede gösterilen ortak bir payda bulmanız gerekecektir . Veya her nohupkomuttan sonra , PID'yi echo ${!}bu gruba göre bir değişkene (tercihen bir dizi) kaydedin ve kontrol edin. Hepsi kaybolduğunda, ikinci fordöngüye
geçebilirsiniz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.