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.


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

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.


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

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.