Come posso avviare un processo in background e controllare quando finisce allinterno di uno script bash? La mia idea è uno script come questo:
launch backgroundprocess & while [ Process is running ];do echo "PROCESS IS RUNNING\r" done; echo "PROCESS TERMINATED"
Answer
La chiave è il comando “wait”:
#!/bin/bash /my/process & /another/process & wait echo "All processes done!"
Commenti
Rispondi
Con wait
puoi avere la granularità di cui hai bisogno:
sleep 1 & PID1=$! sleep 2 & PID2=$! wait $PID1 echo "PID1 has ended." wait echo "All background processes have exited."
Rispondi
Ecco un modo per farlo:
launch backgroundprocess & PROC_ID=$! while kill -0 "$PROC_ID" >/dev/null 2>&1; do echo "PROCESS IS RUNNING" done echo "PROCESS TERMINATED" exit 0
Commenti
- Grazie, questa è sicuramente lunica risposta che risponde alla mia interpretazione della domanda originale (e il motivo per cui ho finito per guardare questa domanda)
- @cuonglm, cosa ci sono più processi? Probabilmente
wait
è più adatto a questo? - @cuonglm cosa fa lopzione -0 per uccidere il comando
- @k_vishwanath segnala se il processo è ancora in esecuzione o meno.
Risposta
Puoi eseguire il tuo processo con nohup e scrivere script di shell per leggere nohup.out che nohup utilizza per accedere.
nohup command &
Commenti
- (1) Al rischio di spaccarsi i capelli,
nohup
' non scrive nulla sunohup.out
; semplicemente crea il file e reindirizza loutput del comando ad esso. (2) Se il comando non ' t produce alcun output, non verrà scritto nulla innohup.out
e questa idea non va da nessuna parte velocemente. (3) Anche secommand
scrive loutput, come puoi sapere quando finisce monitorando quelloutput? - @ G- Forse controllando loutput di
lsof
per vedere senohup
sta ancora utilizzandonohup.out
, ma sono daccordo che questo è un metodo molto complicato. - (4) Quando
command
inizia a funzionare,nohup
non cè più. (1) Sì, sto ripetendo un numero, perché sto ripetendo ciò che ho detto due anni fa:nohup
non scrive nulla innohup.out
. (5) Sì, potresti scrivere uno script di shell per eseguire il ciclo ed eseguirelsof
per vedere senohup.out
è ancora aperto. Ma questa sarebbe una risposta diversa. (6) Anche se lo facessi, sarebbe inaffidabile. E se qualche altro processo aprisse il filenohup.out
? Vorresti davvero controllare se questo processo specifico avevanohup.out
aperto. (7) Ma, se hai intenzione di farlo, perché non controllare semplicemente se il processo è in esecuzione?
Answer
wait
funziona solo per un processo figlio avviato nella stessa shell; è “una funzione di shell, dopotutto.
Per qualsiasi processo in background arbitrario devi lavorare con PID. Quello che nessuno menziona qui è il riciclo del PID del kernel. I moderni sistemi Linux possono riutilizzare abbastanza PID spesso a seconda del carico. Per identificare in modo affidabile il processo serve qualcosa di più del semplice PID. Un approccio semplice è risparmiare tempo quando il processo è iniziato e confrontalo regolarmente con lora di inizio del processo corrente. Se il PID viene riciclato, lora di inizio non sarà la stessa.
Lora di inizio del processo è riportata nel campo 22 in / proc / [pid] / stat . Il tempo è misurato in jiffies (al massimo 10 ms) che fornisce abbastanza precisione per rilevare il riciclaggio degli ID di processo.
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
cmd1 & p=$!; cmd2 & q=$!; while sleep 1; do echo still running ; done& wait $p $q; kill $!;