Hur kan jag starta en process i bakgrunden och kontrollera när den slutar inom ett bash-skript? Min idé är ett skript så här:
launch backgroundprocess & while [ Process is running ];do echo "PROCESS IS RUNNING\r" done; echo "PROCESS TERMINATED"
Svar
Nyckeln är kommandot ”vänta”:
#!/bin/bash /my/process & /another/process & wait echo "All processes done!"
Kommentarer
- Fördel med detta: det bränner INTE CPU tid med en oändlig slinga som löper hela tiden ….;)
- Nackdelen med detta är att du ' inte kan göra något annat medan du väntar , såsom att indikera framsteg för användaren. Endast cuonglm ' s lösning tillåter dig att göra detta.
- @Mark Booth Du kan ange framsteg med ett tredje asynkront jobb. t.ex.:
cmd1 & p=$!; cmd2 & q=$!; while sleep 1; do echo still running ; done& wait $p $q; kill $!;
Svar
Med wait
du kan ha den detaljnivå du behöver:
sleep 1 & PID1=$! sleep 2 & PID2=$! wait $PID1 echo "PID1 has ended." wait echo "All background processes have exited."
Svar
Här är ett sätt att göra det:
launch backgroundprocess & PROC_ID=$! while kill -0 "$PROC_ID" >/dev/null 2>&1; do echo "PROCESS IS RUNNING" done echo "PROCESS TERMINATED" exit 0
Kommentarer
- Tack, detta är definitivt det enda svaret som svarar på min tolkning av den ursprungliga frågan (och anledningen till att jag slutade titta på den här frågan)
- @cuonglm, Vad finns det finns flera processer? Förmodligen är
wait
mer lämplig för det? - @cuonglm vad gör -0 alternativet att döda kommandot
- @k_vishwanath rapporterar det om processen körs fortfarande eller inte.
Svar
Du kan köra din process med nohup och skriva skalskript för att läsa nohup.out-fil som nohup använder för att logga.
nohup command &
Kommentarer
t skriver något till nohup.out
; det skapar bara filen och omdirigerar kommandos utdata till den. (2) Om kommandot ' inte ger någon utdata kommer inget att skrivas till nohup.out
, och denna idé går ingenstans snabbt. (3) Även om command
skriver utdata, hur kan du se när det slutar genom att övervaka utdata?
lsof
för att se om nohup
fortfarande använder nohup.out
, men jag håller med om att detta är en väldigt hårig metod. command
börjar springa, nohup
är borta. (1) Ja, jag upprepar ett nummer för jag upprepar vad jag sa för två år sedan: nohup
skriver ingenting till nohup.out
. (5) Ja, du kan skriva ett skalskript för att slinga och köra lsof
för att se om nohup.out
fortfarande är öppen. Men det skulle vara ett annat svar. (6) Även om du gjorde det skulle det vara opålitligt. Vad händer om någon annan process öppnade filen nohup.out
? Du skulle verkligen vilja kontrollera om den här specifika processen hade nohup.out
öppen. (7) Men om du ska göra det, varför inte bara kontrollera om processen körs? Svar
wait
fungerar bara för en underprocess som startas i samma skal; det är trots allt en skalfunktion.
För alla godtyckliga bakgrundsprocesser behöver du arbeta med PID. Vad ingen här nämner är kärnan PID-återvinning . Moderna Linux-system kan återanvända PID ganska ofta beroende på belastning. Du behöver mer än bara PID för att på ett tillförlitligt sätt identifiera processen. En enkel metod är att spara tid när processen startade och jämför den regelbundet med den aktuella starttiden för processen. Om PID återvinns blir dess starttid inte densamma.
Processens starttid rapporteras som fält 22 i / proc / [pid] / stat fil. Tiden mäts i jiffies (högst 10 ms) vilket ger tillräckligt precision för att upptäcka återvinning av process-ID.
PID=<process ID> START_TIME=$(cut -d " " -f 22 /proc/$PID/stat) while [ "$(cut -d " " -f 22 /proc/$PID/stat 2>/dev/null)" = "$START_TIME" ]; do echo "PROCESS IS RUNNING" sleep 1 done
nohup
<