Mám bash skript, který vypadá takto:
##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 
Chtěl bych vytvořit další smyčku for po první, abych pokračoval dalších 30. Například
##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 
 Chtěl bych pro první sadu úloh dokončit před spuštěním nové sady. Ale kvůli nohup se zdá, že jsou všechny spuštěny současně. 
 Mám nohup, protože se vzdáleně přihlásím na svůj server a spustím tam úlohy a poté zavřu bash. Existuje alternativní řešení? 
Komentáře
Odpovědět
 Chcete použít příkaz wait k udělejte to za vás. Můžete buď zachytit všechny podřízené ID procesů a počkat na ně konkrétně, nebo pokud jsou to jediné procesy na pozadí, které váš skript vytváří, stačí zavolat wait bez argumentu. Například: 
#!/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" 
Odpověď
Několik bodů:
- 
Pokud je vaším cílem
nohupzabránit tomu, aby vzdálený výstup shellu zabil vaše pracovní procesy, měli byste použítnohupna samotný skript, nikoli na jednotlivé pracovní procesy, které vytváří. - 
Jak je vysvětleno zde ,
nohuppouze brání procesům přijímat SIGHUP a od interakce s terminálem, ale nenarušuje vztah mezi shellem a jeho podřízenými procesy. - 
Kvůli výše uvedenému bodu, s nebo bez
nohup, jednoduchéwaitmezi dvěmaforsmyčkami způsobí druhéforbude provedeno až poté, co budou ukončeny všechny podřízené procesy spuštěné prvnímifor. - 
S jednoduchým
wait:čekají se na všechny aktuálně aktivní podřízené procesy a návratový stav je nulový.
 - 
Pokud potřebujete spustit druhou
for, pouze pokud v první chybě nebyly žádné chyby , pak „budete muset uložit každý PID pracovníka s$!a předat je všemwait:pids= for ... worker ... & pids+=" $!" done wait $pids || { echo "there were errors" >&2; exit 1; } 
Komentáře
-  Tam cou Byly by jiné úlohy spuštěné na serveru. Takže ' chci jen počkat na svou dávku .. jsou to R skripty, takže jsou spuštěny pod 
Rnebocc1plusvtoppříkazu -  Také <
 
bych rád používal nohup uvnitř spustit všechny příkazy v " paralelně ". v zásadě se jedná o simulace vědeckého programu. Chci spustit celkem 180 simulací, ale v dávkách 60. Počítadlo také musí jít od 1 do 180. Pokud je udělám po jednom, bude to trvat příliš dlouho.
wait způsobí, že bash počká na úlohy na pozadí, které sama vytvořila, nic jiného. Mohlo by zde dojít k určitému zmatku – tyto smyčky for, uložili jste je do souboru a vyvolali je jako skript (co jsem předpokládal kvůli ##script line), nebo je píšete ručně do terminálu? cat file.txt | while a pids nebyl nastaven mimo smyčku příkaz čekání tedy viděl prázdný $pids řetězec. proč se to stane, je popsáno na  serverfault.com/q/259339 . snadno opravitelné jako while ... < files.txt podle odpovědi na  serverfault.com/a/259346  odpověď
 Použijte fg vestavěné. Čeká na dokončení procesů na pozadí. 
 Podrobnosti zkuste help fg. 
Komentáře
- Skript běží bez kontroly úlohy.
 
Odpovědět
 Pokud vložíte něco jako následující segment kódu mezi vašimi dvěma for smyčkami by to mohlo pomoci. 
flag=0 while [ flag -eq 0 ] do ps -ef | grep "Rscript --vanilla" | grep -v grep > /dev/null flag=${?} sleep 10 done 
 Samozřejmě, pokud vaše aplikace Rscript má šanci, že se nedokončí úspěšně a přetrvává, vaše druhá smyčka for nemusí mít šanci se spustit. Výše uvedený segment kódu předpokládá, že všechny procesy s identifikátorem Rscript --vanilla se dokončí a zmizí správně. Aniž bych věděl, co vaše aplikace dělá a jak běží, musím se na tento předpoklad spolehnout.
EDIT
Ve světle komentářů by to lépe vyhovovalo tvoje potřeby. (zahrnuje váš původní kód i logiku kontroly dokončení)
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 
Komentáře
-  Proces název v 
topzobrazuje buďRněkdy, nebocc1plus. -  V takovém případě budete muset najít společného jmenovatele, který se zobrazí v seznamu 
ps -ef. Nebo po každémnohuppříkazu nahrajte PID do proměnné (nejlépe do pole) pomocíecho ${!}a zkontrolujte tuto skupinu PID. Když všechny zmizí, můžete přejít do druhéforsmyčky 
wait.