egy bash szkript szüneteltetése az előző parancsok befejezéséig

Van egy bash szkriptem, amely a következőképpen néz ki:

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

Szeretnék létrehozni egy másik ciklust az első után, hogy folytatódhasson egy másik 30-mal. Például

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

Szeretném az első befejezett feladatsor az új készlet megkezdése előtt. De a nohup miatt úgy tűnik, hogy mindet egyszerre futtatják.

Azért van nohup, mert távolról bejelentkezem a szerveremre, ott elkezdem a munkákat, majd bezárom a bash-t. Van alternatív megoldás?

Megjegyzések

  • Keresse meg a kézikönyvben a wait beépítettet.

Válasz

A wait parancsot használni szeretné Csináld meg az összes gyerek folyamatazonosítót, és várhat rájuk, vagy ha csak az általad létrehozott háttérfolyamatok vannak, akkor egyszerűen felhívhatod a következőt: wait argumentum nélkül. Például:

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

Válasz

Néhány pont:

  • Ha a nohup paranccsal az a célja, hogy megakadályozza a távoli shell-kijárat megölését a dolgozói folyamatokban, akkor használja a nohup magára a szkriptre, nem pedig az általa létrehozott egyes munkavállalói folyamatokra.

  • Amint azt itt elmagyarázta , nohup csak megakadályozza a folyamatok SIGHUP fogadását és a terminállal való interakciótól, de ez nem szakítja meg a kapcsolatot a héj és gyermekfolyamatai között.

  • A fenti pont miatt , a két for hurok közötti egyszerű wait okozhatja a második for csak az első for által elindított gyermekfolyamatok kilépése után hajtható végre.

  • Egyszerű wait:

    az összes aktív gyermekfolyamatra várnak, és a visszatérési állapot nulla.

  • Ha a második for futtatására van szükség, csak akkor, ha az elsőben nem voltak hibák , akkor minden egyes munkavállaló PID-jét el kell mentenie a $! paranccsal, és mindegyiket át kell adnia a wait címre: = “924c4c51be”>

Megjegyzések

  • Van pár Más szerveren futó munka lehet. Tehát én ' csak a kötegemre akarok várni .. ezek R szkriptek, így R vagy cc1plus a top parancsban
  • Szintén i ' szeretnék nohupot használni az összes parancs futtatásához " párhuzamosan ". alapvetően ezek egy tudományos program szimulációi. Összesen 180 szimulációt szeretnék futtatni, de 60 tételenként. A számlálónak 1-ről 180-ra is el kell mennie. Ha egyenként csinálom őket, akkor túl sokáig tart.
  • wait miatt bash várni fogja az általa kikelt háttérmunkákat, semmi mást. Itt némi zavart okozhat – ezek a for ciklusok, mentetted-e őket egy fájlba, és szkriptként hívtad-e őket (amit feltételeztem, a >

sor), vagy kézzel írja be őket a terminálba?

  • én csináltam cat file.txt | while és a pideket nem a cikluson kívül állítottuk be így a wait parancs üres $pids karakterláncot látott. hogy ez miért történik, a serverfault.com/q/259339 címen tárgyaljuk. könnyen javítható while ... < files.txt néven, amint a (z) serverfault.com/a/259346 címre válaszolnak
  • Csak kíváncsi mi a célja a + jelnek a pids változóval?
  • Válasz

    Használja a fg beépítve. Várakozik, amíg a háttérfolyamatok befejeződnek.

    A részletekért próbálja ki a help fg részt.

    Megjegyzések

    • A parancsfájl job-vezérlés nélkül fut.

    Válasz

    Ha a következő kódszegmenshez hasonlót szúr be a két for hurok között ez segíthet.

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

    Természetesen, ha az alkalmazás Rscript esélye van arra, hogy ne fejezze be sikeresen, és elhúzódjon, előfordulhat, hogy a ciklusod után másodiknak nincs esélye futni. A fenti kódszegmens feltételezi, hogy a Rscript --vanilla azonosítóval rendelkező összes folyamat befejeződik és megfelelően eltűnik. Erre a feltételezésre kell hagyatkoznom anélkül, hogy tudnám, mit és hogyan fut az alkalmazás.

    SZERKESZTÉS

    A megjegyzések fényében ez jobban megfelel a szükségleteid. (tartalmazza az eredeti kódot, valamint a befejezés-ellenőrzési logikát is)

    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 

    Megjegyzések

    • A folyamat A (z) top név néha vagy R, vagy cc1plus.
    • Ebben az esetben meg kell találnia egy közös nevezőt, amely megjelenik a ps -ef listában. Vagy minden nohup parancs után rögzítse a PID-t egy változóba (lehetőleg egy tömbbe) a echo ${!} paranccsal, és ellenőrizze a PID-k ezen csoportját. Amikor ezek mind eltűnnek, folytathatja a második for ciklust

    Vélemény, hozzászólás?

    Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük