È necessario utilizzare job control, che, purtroppo, è un po 'complicato. Se questi sono gli unici processi in background che ci si aspetta sarà in esecuzione, è possibile eseguire un comando come questo:
jobs \
| perl -ne 'print "$1\n" if m/^\[(\d+)\][+-]? +Running/;' \
| while read -r ; do kill %"$REPLY" ; done
jobs
Stampa un elenco di tutti i processi attivi (in esecuzione di posti di lavoro, più di recente finito o lavori terminati), in un formato simile a questo:
[1] Running sleep 10 &
[2] Running sleep 10 &
[3] Running sleep 10 &
[4] Running sleep 10 &
[5] Running sleep 10 &
[6] Running sleep 10 &
[7] Running sleep 10 &
[8] Running sleep 10 &
[9]- Running sleep 10 &
[10]+ Running sleep 10 &
(. Questi sono posti di lavoro che ho lanciato eseguendo for i in {1..10} ; do sleep 10 & done
)
perl -ne ...
sono io utilizzando Perl per estrarre i numeri di lavoro dei processi in esecuzione; puoi ovviamente usare uno strumento diverso se preferisci. Potrebbe essere necessario modificare questo script se il tuo jobs
ha un formato di output diverso; ma l'output sopra riportato è anche su Cygwin, quindi è molto probabilmente identico al tuo.
read -r
legge una riga "raw" dall'input standard e la salva nella variabile $REPLY
. kill %"$REPLY"
sarà qualcosa di simile a kill %1
, che "uccide" (invia un segnale di interruzione a) il numero di posti di lavoro 1. (Da non confondere con kill 1
, che ucciderebbe processo numero 1.) Insieme, while read -r ; do kill %"$REPLY" ; done
passa attraverso ogni numero di posti di lavoro stampato da lo script Perl e lo uccide.
A proposito, la tua for i in {1 .. $num}
non farà quello che ti aspetti, in quanto espansione delle parentesi graffe è gestito prima espansione dei parametri, in modo da quello che hai è equivalente a for i in "{1" .. "$num}"
. (E non si può avere lo spazio bianco all'interno dell'espansione coppia, comunque.) Sfortunatamente, non conosco un'alternativa pulita; Penso che devi fare qualcosa come for i in $(bash -c "{1..$num}")
, oppure passare a un aritmetico for
-loop o whatnot.
Inoltre, non è necessario avvolgere il ciclo while tra parentesi; &
causa già l'esecuzione del lavoro in una subshell.
Sembra bello e pulito, ma non capisco come vengono gestiti i gruppi di processi. È garantito che tutti i processi in background che sto generando e nessun altro siano nello stesso gruppo di processi dello script? – ykaganovich
Sì, questo è il comportamento predefinito per i gruppi di processi. A meno che tu non abbia scritto un codice che fa esplicitamente una chiamata di sistema per cambiare un gruppo del processo, starai bene. –
@RussellDavis Questo è così pulito e funziona molto bene. Ho dovuto aggiungere trap a tutti gli script di shell che ho generato dallo script master per farlo funzionare. – nograpes