Esegui lo stesso comando più volte in background


14

Come è possibile eseguire più comandi e metterli in background usando bash?

Per esempio:

$ for i in {1..10}; do wait file$i &; done

dove wait è un binario personalizzato.

In questo momento ricevo un errore:

syntax error near unexpected token `;'

quando si esegue il comando sopra.

Una volta in background i comandi dovrebbero essere eseguiti in parallelo.


1
Sto dicendo che non ti riferisci a: nohupconsentirti di eseguire un comando in background
Dave Hamilton

3
L'errore che stai vedendo è dovuto &e ;sono entrambi "terminatori di comando". Non è necessario utilizzare entrambi: for ...; do wait $arg & donefunzionerà.
Glenn Jackman,

@glenn jackman. Sì, l'ho provato dopo aver pubblicato la domanda. Non è necessario per entrambi; e &
Sebi il

3
Per i futuri lettori, un collegamento alla documentazione : "Un elenco è una sequenza di una o più condutture separate da uno degli operatori ';', '&', '&&' o '||', e facoltativamente terminato da uno di ';', '&' o una nuova riga ". (enfasi mia)
glenn jackman,

Risposte:


21

Il &, proprio come ;è un operatore di terminazione elenco . Hanno la stessa sintassi e possono essere utilizzati in modo intercambiabile (a seconda di ciò che si desidera fare). Questo significa che non vuoi, o non command1 &; command2hai bisogno, tutto ciò di cui hai bisogno è command1 & command2.

Quindi, nel tuo esempio, potresti semplicemente scrivere:

for i in {1..10}; do wait file$i & done

e ogni waitcomando verrà lanciato in background e il loop passerà immediatamente al successivo.


4

Per motivi di compatibilità, utilizzare il modulo posix anziché l'espansione:

for i in $(seq 1 10); do (./wait file$i &); done

1
Nota che seqnon è un comando POSIX e generalmente si trova solo sui sistemi GNU. Il comportamento o $(...)(e $i) dipende dal valore corrente di $IFS. Inoltre (cmd &), facendo ciò , cmdsarà figlio di una subshell, quindi non sarai in grado di aspettare e ottenere il suo stato di uscita, ad esempio.
Stéphane Chazelas,

2

È possibile raggruppare i comandi e mettere i comandi raggruppati in background. Piace :

$ for i in {1..10}; do ((wait file$i)&); done

Non è necessario usare le parentesi interne ...
marc

devi solo usare le parentesi interne se vuoi mettere in background più comandi come richiesto nella domanda. Like ((sleep 1; wait file $ i) &);
mazs

2

Il tuo binario ha davvero un nome wait? Non consiglio di farlo, perché waitè incorporato una shell.

Credo che bash non analizzi bene un ciclo di una riga che avvia i processi in background. Ti suggerisco di cambiare il codice in:

$ for i in {1..10}; do ./wait file$i & echo "Running 'wait' using PID=$!..."; done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.