Como posso executar vários comandos que possuem & em uma linha de comando?

7

Eu encontrei um problema de dor de cabeça. Eu quero executar mulitple comandos em segundo plano, então eu quero iniciá-los em bash um por um. É fácil iniciar o comando no linux em segundo plano, assim:

myCommand &

Também é fácil iniciar vários comandos, assim:

myCommand1 & myCommand2

ou

myCommand1 ; myCommand2

Mas se eu quiser executar vários comandos em segundo plano, tentei o seguinte formato de comando, mas falhei:

myCommand1 & && myCommand2 &

ou

myCommand1 & ; myCommand2 &

Ambos os formatos falham. Como posso executar vários comandos que possuem & em uma linha de comando?

    
por Clock ZHONG 29.12.2017 / 04:38

2 respostas

13

Use ().

Se você quiser executá-los sequencialmente:

(myCommand1; myCommand2) &

ou

(myCommand1 &) && (myCommand2 &)

Se você quiser que eles sejam executados paralelamente:

myCommand1 & myCommand2 &

No bash você também pode usar isto (espaço atrás do {e o; são obrigatórios):

{ myCommand1 && myCommand2; } &
    
por Rinzwind 29.12.2017 / 09:59
13

Suponho que você quer isso:

myCommand1 & myCommand2 &

Isso inicia myCommand1 e envia para o segundo plano como é seguido pelo "E" comercial, então imediatamente inicia myCommand2 e envia isso também para o segundo plano, liberando o shell novamente.

Listas

Para entender melhor, você pode substituir pipeline pelo comando aqui.

  

Uma lista é uma sequência de um ou mais pipelines separados por um dos   os operadores ; , & amp; , & amp; & amp; & ou || e, opcionalmente, terminados por um dos   ; , & amp; ou .

     

Se um comando for finalizado pelo operador de controle & amp; , o   O shell executa o comando em segundo plano em um subshell. o   shell não espera que o comando termine e   o status de retorno é 0. Comandos separados por um ; são executados   sequencialmente; o shell aguarda que cada comando termine em   virar. O status de retorno é o status de saída do último comando   executado.

     

As listas AND e OR são seqüências de um ou mais pipelines separados   pelos operadores de controle & amp; & amp; e || , respectivamente.
Source: man bash

Vamos dividir isso em exemplos. Você pode criar uma lista combinando comandos e separando-os com um destes: ; & && || :

command1 ; command2  # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2  # runs simultaneously

Você pode finalizar listas com um destes: ; & <newline> .
Normalmente você executa um comando ou lista pressionando Enter , que é igual a <newline> . O ponto e vírgula ; serve exatamente o mesmo propósito, especialmente em scripts. O e comercial & no entanto inicia o (s) comando (s) em um subshell em segundo plano, liberando imediatamente o shell.

Você pode usar round () ou chaves {} para outras listas de grupos, a diferença é que os colchetes geram um subshell e os cacheados não. Os colchetes encaracolados precisam de um espaço após o primeiro e um ponto-e-vírgula ou uma nova linha antes do colchete de fechamento. Por exemplo:

# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) & 
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &

Isso pode ficar bastante complicado, se você não tiver certeza use true e false para testar se a construção funciona como esperado:

$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2

Job Control

O comando jobs exibe uma lista das tarefas em segundo plano que estão em execução ou foram concluídas recentemente no shell atual. Há vários atalhos de teclado e comandos para controle de tarefas:

  • Ctrl + Z digita o caracter suspender que faz com que o processo atualmente em execução no primeiro plano seja interrompido, não é terminado, mas permanece no jobs list
  • Ctrl + Y digita o caractere delayed suspend que faz com que o processo atualmente em execução no primeiro plano seja interrompido quando tenta ler a entrada do terminal
  • fg = % traz um processo para o primeiro plano, iniciando-o, se necessário, você pode especificar o processo da seguinte forma:

     %       # last process in the jobs list
     %1      # 1st process in the jobs list
     %abc    # process beginning with the string “abc”
     %?abc   # process containing the string “abc” anywhere
    
  • bg = %& leva um processo para o plano de fundo, iniciando-o, se necessário:

     %&      # last process in the jobs list
     %1&     # 1st process in the jobs list
     %abc&   # process beginning with the string “abc”
     %?abc&  # process containing the string “abc” anywhere
    
  • wait espera que um processo em segundo plano seja concluído e retorna seu status de finalização:

     wait %1 # 1st process in the jobs list
    

    Imagine que você iniciou um longo processo ( jobs revela seu número 3) e percebe que deseja que o computador seja suspenso quando terminar, além de echo uma mensagem se o processo não tiver êxito:

     wait %3 || echo failed ; systemctl suspend
    
por dessert 29.12.2017 / 09:42