Introduzione
wait è un comando che attende il completamento dei lavori (jobs) dati e restituisce lo stato di uscita del comando atteso.
Poiché il comando wait
influisce sull'ambiente di esecuzione della shell corrente, è implementato come comando integrato nella maggior parte delle shell.
In questo articolo, esploreremo il comando wait
integrato di Bash.
Il comando wait in Bash
La sintassi generale dell'integrato wait
assume la seguente forma:
wait [options] ID
ID
è l'ID processo o lavoro (job). Se ID
non viene specificato, il comando attende il completamento di tutti i processi secondari in background.
Il comando wait
restituisce lo stato di uscita dell'ultimo comando atteso.
Ad esempio, per attendere un processo in background con PID 7654
, dovresti usare:
wait 7654
Quando vengono forniti più processi, il comando attende il completamento di tutti i processi.
I job vengono specificati utilizzando la specifica del job jobspec, che è un modo per fare riferimento ai processi che compongono il job. Un jobspec inizia con un simbolo di percentuale seguito dal numero del job (%n
). Ecco un esempio:
Esegui un comando in background:
rsync -a /home /tmp/home &
L'ID del job della shell (racchiuso tra parentesi) e l'ID del processo verranno visualizzati sul terminale:
[2] 54377
Per attendere il job, eseguire il comando wait
seguito dalla specifica del job:
wait %2
Quando viene richiamato con l'opzione -n
, il comando attende solo il completamento di un singolo job dai dati pid o jobspecs e restituisce il suo stato di uscita. Se non vengono forniti argomenti, wait -n
attende il completamento di qualsiasi job in background e restituisce lo stato di uscita del job.
wait -n 45432 54346 76573
Nell'esempio sopra, wait -n
stampa solo lo stato di ritorno del job che esce per primo; non mostra il PID del job . Se vuoi ottenere il job pid o jobspec per il quale viene restituito lo stato di uscita, usa l'opzione -p
per assegnarlo a una variabile:
wait -p job_id -n 45432 54346 76573
L'opzione -p
è stata introdotta in Bash 5.1. Se utilizzi una versione precedente di Bash, riceverai un errore di "invalid option".
L'opzione -f
dice al comando wait
di attendere che ogni pid o jobspec termini effettivamente prima di restituire il suo codice di uscita, invece di tornare quando lo stato del job viene modificato. Questa opzione è valida solo quando il controllo del job è abilitato. Per impostazione predefinita, il controllo del job è abilitato solo per i prompt interattivi.
Esempi
wait
è tipicamente utilizzato negli script della shell che generano processi figli che vengono eseguiti in parallelo.
Per illustrare come funziona il comando, creare il seguente script:
#!/bin/bash
sleep 30 &
process_id=$!
echo "PID: $process_id"
wait $process_id
echo "Exit status: $?"
Spieghiamo il codice riga per riga:
- La prima riga si chiama shebang e dice al sistema operativo quale interprete usare per analizzare il resto del file.
- Stiamo usando il comando
sleep
per emulare un processo in background che richiede tempo. $!
è una variabile Bash interna che memorizza il PID dell'ultimo job eseguito in background. In questo esempio, questo è il PID del comandosleep
. Stiamo memorizzando il PID in una variabile (process_id
).- Stampa il numero PID.
- Il PID viene passato al comando
wait
che attende il completamento del comandosleep
. - Stampa lo stato di uscita del comando
wait
.$?
è una variabile Bash interna che mantiene lo stato di uscita dell'ultimo comando eseguito.
Se esegui lo script, stamperà qualcosa del genere:
PID: 36353
Exit status: 0
Ecco un esempio che utilizza l'opzione -n
:
#!/bin/bash
sleep 3 &
sleep 30 &
sleep 5 &
wait -n
echo "First job completed."
wait
echo "All jobs completed."
Quando lo script viene eseguito, genera 3 processi in background. wait -n
attende il completamento del primo job e la stampa dell'istruzione echo. wait
attende il completamento di tutti i processi secondari in background.
first job completed
all jobs completed
L'ultimo esempio spiega l'opzione -f
. Apri il terminale ed esegui:
sleep 3600 &
[1] 46671
Usa il comando wait per il seguente il processo:
wait 46671
Apri un altro terminale e interrompi il processo con il comando kill
:
kill -STOP 46671
Una volta modificato lo stato del processo, il comando wait
verrà completato e restituirà il codice di uscita del processo.
Ora, ripeti gli stessi passaggi, ma questa volta usa wait -f $pid
:
sleep 3600 &
Interrompi il processo dall'altro terminale:
kill -STOP 46671
Questa volta il comando wait
non verrà completato. Verrà eseguito fino al termine del processo sleep
.
Conclusione
Il comando wait
attende il completamento dei jobs specificati e restituisce il codice di uscita del job.