Como executo vários comandos de segundo plano no bash em uma única linha?

169

Normalmente, eu executo vários comandos com algo assim:

sleep 2 && sleep 3

ou

sleep 2 ; sleep 3

mas e se eu quiser executá-los em segundo plano a partir de um comando de linha de comando?

sleep 2 & && sleep 3 &

não funciona E nem substituir &&por;

Existe uma forma de fazer isso?

Palace Chan
fonte
8
Use ()para cercar o comando.
N / a
1
unix.stackexchange.com/questions/67006/…
Ciro Santilli escreveu:

Respostas:

319

Exatamente como você deseja que eles funcionem? Se você deseja que eles sejam iniciados em segundo plano e executados sequencialmente , faça algo assim:

(sleep 2; sleep 3) &

Se, por outro lado, você deseja que eles sejam executados paralelamente em segundo plano, você pode fazer o seguinte:

sleep 2 & sleep 3 &

E as duas técnicas podem ser combinadas, como:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

Bash sendo bash, muitas vezes há várias técnicas diferentes para realizar a mesma tarefa, embora algumas vezes com diferenças sutis entre elas.

Kitsune
fonte
20
Essa é uma resposta concisa e bem pensada que "ensina um homem a pescar" por toda a vida. Obrigado.
Ambrus
2
O que acontece se o fizermos sleep 2 && sleep 3 &? Eu tentei no bash e parece funcionar da mesma maneira (tentei com eco).
Wajahat
@HakanBaba, Sim, de fato, cria um subshell em segundo plano.
Douwe van der Leest 21/05/19
3
@ Wajahat, você tentou sleep 2 && echo "foo" && sleep 3 & echo "bar""? O &&operador diz ao shell para executar o comando antes dele, e somente se esse comando for executado sem nenhum erro, o shell executará o comando subseqüente. Isso é essencialmente diferente de ;, porque ;permite que o comando subseqüente seja executado independentemente do status de saída do comando anterior, a menos que tenha sido um erro fatal. O &comando diz ao shell para executar todos os comandos "conectados" que o precedem, em segundo plano. "conectado" aqui significa que o comando faz parte de um pipe ( |) ou de um operador lógico.
Douwe van der Leest 21/05/19
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.no manual do bash.
jinbeom hong
49

Você precisa adicionar alguns parênteses em sua última versão -

(sleep 2 &) && (sleep 3 &)

ou isso também funciona -

(sleep 2 &) ; (sleep 3 &)
iagreen
fonte
Nota: Quando uma lista é usada &, seu status de saída é sempre zero. Portanto, os dois casos acima fazem a mesma coisa (o shell executa os dois lados de forma assíncrona ).
jinbeom hong 13/06
9

Para executar vários comandos em segundo plano, é necessário adicionar o &final de cada comando. ex: (command1 &) && (command2 &) && (command3 &)

erva
fonte
5

As respostas acima usam parênteses. O Bash também pode usar chaves para uma finalidade semelhante:

{ sleep 2 && sleep 3; } &

Observe que as chaves são mais exigentes quanto à sintaxe - o espaço após {, o espaço anterior }e o ponto e vírgula final são necessários. Em algumas situações, os aparelhos são mais eficientes porque não bifurcam um novo subshell. Nesse caso, não sei se faz diferença.

Greg Reagle
fonte
1
Que tal { sleep 2; sleep 3; } &?
precisa saber é o seguinte
4

Isso funciona:

$(sleep 2 &) && sleep 3 &

Também você pode fazer:

$(sleep 2 && sleep 3) &
higuaro
fonte
0

Eu tenho a mesma missão também. Eu tentei (sleep2 ; fg )& sleep3 ; fg, está funcionando. E quando você pressiona ctrl + c dobrado, os dois processos podem ser interrompidos.

dingyang wang
fonte
0

Você pode usar a substituição do comando bash $(command)assim:

$(command1 ; command2) &

Observe que stdin e stdout ainda estão vinculados ao processo pai e redirecionar pelo menos o stdout pode ser complicado. Então, alternativamente, você pode encadear os comandos em uma única linha e passar a string para o bashcomando para gerar um novo processo que manipulará a execução.

bash -c "command1 ; command2" & 

Isso é especialmente útil em um script bash quando você precisa executar vários comandos em segundo plano.

Essas duas instruções devem ser equivalentes. Um processo bash é gerado nos dois casos para manipular o comando (cadeia de comandos) e o& no final desanexa a execução.

Desta vez, você pode adicionar &>/dev/nullantes do &final do comando para redirecionar pelo menos o stdout e evitar a saída no stdout do processo pai. Algo como:

bash -c "command1 ; command2" &>/dev/null &
Bemipefe
fonte
-1

Se você deseja executar vários comandos sequencialmente , existe um método realmente simples que funciona em qualquer lugar: Criando um arquivo! O benefício desse método é que ele é limpo e simples.

Primeiro, crie seu arquivo com um nome, por exemplo commands.sh. Em seguida, coloque seus comandos lá. Aqui está uma amostra:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

OK, agora estamos no último passo. Para executar comandos em segundo plano (sequencialmente), basta executar:

$ sh commands.sh &
MAChitgarha
fonte