pause et bash-script, indtil tidligere kommandoer er færdige

Jeg har et bash-script, der ligner følgende:

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

Jeg vil gerne oprette en anden til loop efter den første for at fortsætte til en anden 30. For eksempel

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

Jeg vil gerne have det første sæt job, der er afsluttet, før du starter det nye sæt. Men på grund af nohup ser det ud til, at de alle køres samtidigt.

Jeg har nohup, fordi jeg logger eksternt på min server og starter jobbet der og lukker derefter min bash. Er der en alternativ løsning?

Kommentarer

  • Søg i manualen til wait indbygget.

Svar

Du vil gerne bruge kommandoen wait til gør dette for dig. Du kan enten fange alle børnene behandle ider og vente på dem specifikt, eller hvis de er de eneste baggrundsprocesser, som dit script opretter, kan du bare ringe til wait uden argument. For eksempel:

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

Svar

Et par punkter:

  • Hvis dit mål med nohup er at forhindre, at en ekstern shelludgang dræber dine medarbejderprocesser, skal du bruge nohup på selve scriptet, ikke på de individuelle medarbejderprocesser, det opretter.

  • Som forklaret her , nohup forhindrer kun processer i at modtage SIGHUP og fra at interagere med terminalen, men det bryder ikke forholdet mellem skallen og dens underordnede processer.

  • På grund af ovenstående punkt med eller uden nohup, en simpel wait mellem de to for sløjfer forårsager den anden for skal kun udføres, efter at alle underordnede processer startet af den første for er afsluttet.

  • Med en simpel wait:

    der ventes på alle aktuelt aktive underordnede processer, og returstatus er nul.

  • Hvis du kun skal køre den anden for hvis der ikke var nogen fejl i den første , så skal du gemme hver arbejdstagers PID med $! og videregive dem alle til wait:

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

Kommentarer

  • Der cou Det ville være andre job, der kører på serveren. Så jeg ' vil kun vente på min batch .. de er R-scripts, så de køres under R eller cc1plus i top kommandoen
  • Også jeg ' vil gerne bruge nohup inde at køre alle kommandoerne i " parallelt ". dybest set er dette simuleringer til et videnskabeligt program. Jeg vil køre 180 simuleringer i alt, men i batches på 60. Tælleren skal også gå fra 1 til 180. Hvis jeg gør dem en ad gangen, vil det tage for lang tid.
  • wait får bash til at vente på de baggrundsjob, som det skabte selv, intet andet. Der kan være en vis forvirring her – disse for sløjfer, gemte du dem i en fil og påkaldte dem som et script (hvad jeg antog på grund af ##script linje), eller skriver du dem manuelt i terminalen?
  • Jeg lavede cat file.txt | while og pidserne blev ikke sat uden for sløjfen så ventekommandoen så en tom $pids streng. hvorfor dette sker diskuteres på serverfault.com/q/259339 . let fast som while ... < files.txt som svaret på serverfault.com/a/259346
  • Bare nysgerrig hvad er formålet med + tegn med pids-variablen?

Svar

Brug fg indbygget. Det venter, indtil baggrundsprocesser er færdige.

Prøv help fg for detaljer.

Kommentarer

  • Et script kører uden jobkontrol.

Svar

Hvis du indsætter noget i retning af følgende kodesegment imellem dine to for sløjfer, kan det hjælpe.

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

Selvfølgelig, hvis din applikation Rscript har en chance for ikke at fuldføre og dvæle rundt, din anden for loop har muligvis ikke en chance for at løbe. Kodesegmentet ovenfor antager, at alle processer med identifikatoren Rscript --vanilla fuldføres og forsvinder korrekt. Uden at vide, hvad din ansøgning gør, og hvordan den kører, er jeg nødt til at stole på denne antagelse.

REDIGER

På baggrund af kommentarerne passer dette bedre dine behov. (den inkluderer din originale kode samt kontrollogik for færdiggørelse)

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 

Kommentarer

  • Processen navn i top viser enten R undertiden eller cc1plus.
  • I så fald skal du finde en fællesnævner, der vises i ps -ef -listen. Eller efter hver nohup -kommando skal du registrere PID til en variabel (helst en matrix) ved at echo ${!} og kontrollere for denne gruppe af PIDer. Når de alle forsvinder, kan du gå videre til den anden for loop

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *