Como executar o novo comando background sequencialmente se eu já tiver um comando background nohup em execução?

2

Digamos que já tenha um comando de execução em segundo plano1

nohup command1 &

Agora quero enviar o comando2 para o segundo plano, mas não quero que o comando2 seja executado imediatamente. Eu quero comando2 para começar a correr depois de terminar o comando1.

Como posso conseguir isso?

    
por user15964 16.11.2013 / 14:58

4 respostas

1

Você não disse qual shell está executando. Isso ajuda. Você está pedindo para usar sequencialmente o software que foi criado para executar as coisas em paralelo. A resposta curta para muitas pessoas é que você não pode, mas há algumas idéias que você poderia experimentar.

O primeiro, e não sequencial garantido, é enviar o trabalho para a fila em lote usando o comando em lote. É muito simples.

Outra maneira é escrever um script que permita enviar comandos para ele da mesma forma que o lote.

Suponho que você poderia escrever um script que seja executado em segundo plano e permita que apenas um trabalho em segundo plano, além dele mesmo, seja concluído por vez.

De tudo isso, sua melhor aposta é o comando em lote para o qual foi criado. Eu posso adaptar minha resposta muito melhor se souber mais sobre o cenário. Por exemplo, você precisa inspecionar o resultado do comando anterior antes de executar o próximo comando na sequência? Por que você não está digitando todos os comandos em um arquivo e executando o arquivo?

Diga-me mais e posso ajudá-lo mais. Costa

    
por 16.11.2013 / 16:17
1

faz um sub shell?

nohup (commancd1;command2) &
    
por 17.11.2013 / 10:43
1

Assumindo o bash e você está iniciando os jobs no mesmo shell, você pode usar o comando wait .

wait: wait [id]
Wait for job completion and return exit status.

Waits for the process identified by ID, which may be a process ID or a
job specification, and reports its termination status.  If ID is not
given, waits for all currently active child processes, and the return
status is zero.  If ID is a a job specification, waits for all processes
in the job's pipeline.

Então:

sleep 60 &
wait %%; echo nextjobs; sleep 60 &

Infelizmente wait deve ser chamado do mesmo shell que é o pai do processo que você está esperando. Isso significa que você não seria capaz de esperar em segundo plano. Ou seja, o exemplo acima bloqueia até que o primeiro trabalho seja concluído e, em seguida, envia o segundo trabalho para o segundo plano.

    
por 17.11.2013 / 15:47
0

Se o seu Unix implementar o comando fuser , essa seria a maneira mais fácil:

while [ "$(fuser nohup.out 2>/dev/null)" ]; do sleep 2; done
command2

Certifique-se de executá-lo no mesmo diretório do comando1.

Um pouco de explicação:

Quando você executa um comando com nohup , um arquivo chamado nohup.out é criado para armazenar a saída e o erro padrão do comando.

O comando que sugeri está monitorando esse arquivo nohup.out para ver se ele ainda está aberto. Se for esse o caso, significa que o primeiro processo, command1 , ainda está em execução. Nesse caso, o loop while aguarda dois segundos e tente novamente. Quando command1 terminar, o arquivo nohup.out não será mais usado e o loop será deixado, permitindo que command2 seja executado. Observe que isso não funcionará se outro processo usar nohup.out posteriormente, como alguém executando tail -f nohup.out .

Editar: Se o sistema operacional não fornecer fuser , aqui está uma maneira portátil:

1: identifique o ID do processo em segundo plano. Se você acabou de executar o comando nohup , você pode simplesmente obtê-lo com este comando se digitado logo após nohup:

pid=$!

Caso contrário, use um dos seguintes:

pgrep command1
ps -eo pid,comm| grep -w [c]ommand1
top

ou qualquer método semelhante e defina a variável pid de acordo.

Quando terminar, execute este comando:

while kill -0 $pid; do sleep 2; done
command2 

Esperará que command1 seja concluído antes de lançar command2 .

    
por 16.11.2013 / 16:32

Tags