Execute o mesmo comando várias vezes em segundo plano

14

Como é possível executar vários comandos e colocá-los em segundo plano usando o bash?

Por exemplo:

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

onde wait é um binário personalizado.

No momento, recebo um erro:

syntax error near unexpected token `;'

ao executar o comando acima.

Uma vez em segundo plano, os comandos devem ser executados em paralelo.

Sebi
fonte
1
Estou ashuming sua não referindo-se: nohupo que lhe permite executar um comando em segundo plano
Dave Hamilton
3
O erro que você está vendo é devido &e ;é "terminador de comando". Você não precisa usar os dois: for ...; do wait $arg & donefuncionará.
Glenn Jackman
@glenn jackman. Sim, eu realmente tentei depois de postar a pergunta. Não há necessidade de ambos; e &
Sebi 23/03
3
Para futuros leitores, um link para a documentação : "Uma lista é uma sequência de um ou mais pipelines separados por um dos operadores ';', '&', '&&' ou '||' e, opcionalmente, finalizados por um de ';', '&' ou uma nova linha ". (grifo meu)
Glenn Jackman
stackoverflow.com/q/14753491/560648
Lightness Races com Monica

Respostas:

21

O &, assim como ;é um operador de terminador de lista . Eles têm a mesma sintaxe e podem ser usados ​​de forma intercambiável (dependendo do que você deseja fazer). Isso significa que você não quer, nem precisa command1 &; command2, tudo o que precisa é command1 & command2.

Então, no seu exemplo, você pode escrever:

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

e cada waitcomando será iniciado em segundo plano e o loop passará imediatamente para o próximo.

terdon
fonte
4

Por uma questão de compatibilidade, use o formulário posix em vez de expansão:

for i in $(seq 1 10); do (./wait file$i &); done
marc
fonte
1
Observe que seqnão é um comando POSIX e geralmente é encontrado apenas em sistemas GNU. O comportamento ou $(...)(e $i) depende do valor atual de $IFS. Observe também que, ao fazer (cmd &), cmdserá filho de um subshell, portanto você não poderá esperar e obter o status de saída, por exemplo.
Stéphane Chazelas 23/03
2

Você pode agrupar os comandos e colocar os comandos agrupados em segundo plano. Gostar :

$ for i in {1..10}; do ((wait file$i)&); done
mazs
fonte
Não há necessidade de usar os parênteses internos ...
Marc
você só precisará usar os parênteses internos se quiser colocar em segundo plano vários comandos, conforme solicitado na pergunta. Like ((sono 1; aguarde o arquivo $ i) &);
mazs
2

Seu binário é mesmo nomeado wait? Eu não recomendo fazer isso, porque waité um shell embutido.

Acredito que o bash não analisa bem um loop de uma linha que inicia processos em segundo plano. Eu sugiro que você altere o código para:

$ for i in {1..10}; do ./wait file$i & echo "Running 'wait' using PID=$!..."; done
Anderson Medeiros Gomes
fonte