2010-02-18 16 views
7

L'attesa non è attesa per l'arresto di tutti i processi figlio. Questo è il mio script:Rendere il comando "Wait" di linux attendere TUTTI i processi figlio

#!/bin/bash 

titlename=`echo "[email protected]"|sed 's/\..\{3\}$//'` 
screen -X title "$titlename" 

/usr/lib/process.bash -verbose [email protected] 

wait 

bash -c "mail.bash [email protected]" 
screen -X title "$titlename.Done" 

non ho accesso a /usr/lib/process.bash, ma è uno script che cambia di frequente, quindi vorrei fare riferimento ... ma in quello script:

#!/bin/ksh 
#lots of random stuff 
/usr/lib/runall $path $auto $params > /dev/null 2>&1& 

mio problema è che runall crea un file di registro ... e mail.bash è supponiamo di posta me che file di log, ma l'attesa non è in attesa di runall per finire, sembra solo stai aspettando il process.bash per finire. C'è comunque, senza accesso a process.bash, o cercando di mantenere la mia versione aggiornata di process.bash, per fare aspettare l'attesa correttamente runall per finire? (Il file di log sovrascrive il precedente esecuzione, quindi non si può semplicemente verificare la presenza del file di registro, dal momento che c'è sempre uno lì)

Grazie, Dan

+0

Ci può fornire con le parti pertinenti delle 'ps -ef 'dopo che 'wait' ha finito? Questo dovrebbe mostrare quali processi sono in esecuzione e quale processo è figlio di quale altro processo ... – Heinzi

+0

Il mio script e Process.bash finiscono quasi istantaneamente. L'unico processo rimanente è runall, che viene eseguito con PID casuali. – Dan

risposta

9
(
    . /usr/lib/process.bash -verbose [email protected] 
    wait 
) 

Invece di lasciare che avviare il sistema operativo process.bash, questo crea una subshell, esegue tutti i comandi in process.bash come se sono stati inseriti nel nostro script di shell, e attende all'interno di quella subshell.

Ci sono alcuni avvertimenti a questo, ma dovrebbe funzionare se non stai facendo nulla di insolito.

+0

Wow ...quindi, esegui tutto perché un processo figlio del mio script? Questo ha funzionato come un fascino (ho dovuto cambiare il mio script in ksh per abbinare process.bash). Ctrl + C interrompe solo l'attesa, anziché la corsa ... Idealmente, sarei in grado di eseguire process.bash senza la sola "&", ma non posso modificare quel codice e non voglio continuare ad aggiornarlo il mio codice ogni volta process.bash cambia. Grazie. – Dan

+3

Per far sì che Ctrl-C interrompa il processo in background, utilizzare trap e kill: 'pid = $ !; trap "kill $ pid; wait $ pid; exit 0" SIGINT SIGTERM; aspetta $ pid' –

4

wait attende solo per i bambini diretti; se qualche bambino genera i propri figli, non li aspetterà.

+0

C'è comunque intorno a questo? Se voglio che aspetti tutti i bambini, diretti e indiretti? – Dan

+1

L'unico altro modo è attendere PID o jobspec. –

2

Il problema principale è che poiché process.bash è terminato il processo runall sarà orfano e di proprietà di init (PID 1). Se si guarda l'elenco di processi runall, non si avrà più alcuna connessione visibile con il processo poiché lo script intermedio process.bash è terminato. Non c'è modo di usare ps --ppid o qualcosa di simile per cercare questo processo "nipote" una volta che è rimasto orfano.

È possibile wait su un PID specifico. Conosci il PID del processo runall? Se c'è solo un tale processo si potrebbe provare questo, che attendere che tutte esecuzione runall s:

wait `pidof runall` 
+0

Questo non funziona poiché la corsa non è figlia dello script originale. – abhaga

1

Si potrebbe recuperare il PID del processo per il quale si vuole aspettare

E poi passare questo PID come argomento per il comando Wait

Problemi correlati