Processos síncronos em segundo plano

1

Eu quero lançar dois processos em segundo plano, mas preciso que o segundo espere até que o primeiro termine. Ambos serão muito longos, então eu também preciso poder sair do terminal.

No momento, tenho isto:

 nohup ./script1.sh $arg1 &    
 wait
 nohup ./script1.sh $arg2 &

O problema aqui é que não consigo usar meu terminal ou sair enquanto aguardo. Eu também tentei capturar o comando '1 PID e alimentá-lo para esperar, mas o problema persiste.

Em resumo, quero iniciar o script principal chamando script1 e script2, fecho meu terminal e abri-lo 5 dias depois. Neste momento, eu preciso que o script1 seja executado primeiro, e somente depois que ele terminar o script2 pode começar a ser executado.

    
por pilu 17.04.2016 / 11:21

1 resposta

4

Conceitos básicos ...

Para executar dois scripts um após o outro, você coloca um ponto e vírgula entre eles: script1 args ...; script2 args ... ou em um script, você também pode colocá-los em duas linhas como esta:

#!/bin/sh
script1 args ...
script2 args ...

Isso também funciona se você quiser executá-los em segundo plano. Você acabou de colocá-los em um subshell e colocar o subshell no fundo: (script1 args ...; script2 args ...) & ou:

#!/bin/sh
(
  script1 args ...
  script2 args ...
) &

Se você deseja executar o segundo script somente se o primeiro script tiver saído com êxito (com o código 0 ), você poderá substituir o ponto e vírgula por && : script1 args ... && script2 args ...

... com nohup

Mas nohup quer executar um comando e um subshell não é um único comando, é uma construção de shell que funciona apenas no shell. Mas podemos iniciar um novo shell que executa os dois scripts, passar isso como um comando para nohup e juntar tudo isso em segundo plano:

#!/bin/sh
nohup sh -c 'script1 args ...; script2 args ...' &

Se você tiver variáveis em args ... você terá que usar aspas duplas e terá que tomar um cuidado especial para escapar delas corretamente, então aqui está outra maneira:

... com garfo duplo

O shell só conhece e se preocupa com seus filhos diretos. Você será avisado se ainda houver processos sendo executados em segundo plano quando você tentar sair, e esses filhos diretos serão mortos se você realmente sair do shell. A solução é colocar um subshell no fundo que coloca o seu comando em segundo plano. Seu shell só saberá sobre o subshell e não sobre o comando. Mas você não pode confiar na mágica de redirecionamento de nohub e precisa configurar seu próprio redirecionamento:

#!/bin/sh
(
  # outer subshell, will be known to your shell
  (
    # inner subshell, "hidden" from your interactive shell
    script1 "$args" ... > ~/script1.stdout.log 2> ~/script1.stderr.log
    script2 "$args" ... > ~/script2.stdout.log 2> ~/script2.stderr.log
    # note that you can do normal quoting here
  ) &
) &
    
por 17.04.2016 / 11:29