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
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 anohup
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ásodikfor
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 await
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
vagycc1plus
atop
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
miattbash
várni fogja az általa kikelt háttérmunkákat, semmi mást. Itt némi zavart okozhat – ezek afor
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?
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 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 vagyR
, vagycc1plus
. - Ebben az esetben meg kell találnia egy közös nevezőt, amely megjelenik a
ps -ef
listában. Vagy mindennohup
parancs után rögzítse a PID-t egy változóba (lehetőleg egy tömbbe) aecho ${!}
paranccsal, és ellenőrizze a PID-k ezen csoportját. Amikor ezek mind eltűnnek, folytathatja a másodikfor
ciklust
wait
beépítettet.