Finalizando um script de shell bash rodando em segundo plano

14

Costumo usar scripts de shell bash para executar comandos simples para muitos arquivos diferentes. Por exemplo, suponha que eu tenha o seguinte script shell bash , chamado script.sh , que executa o programa / comando foo em três arquivos de texto "a.txt" , "b.txt" , "c.txt" :

#!/bin/bash

for strname in "a" "b" "c"
do
foo $strname".txt"
done

Além disso, suponha que foo $strname".txt" seja lento, portanto a execução do script demorará muito tempo (horas ou dias, por exemplo). Por causa disso, eu gostaria de usar nohup para que a execução continue mesmo se o terminal estiver fechado ou desconectado. Eu também gostaria que o script fosse imediatamente para o segundo plano, então usarei o operador & . Assim, usarei o seguinte comando para chamar script.sh :

nohup bash script.sh &

Isso funciona bem para executar o script em segundo plano e sem desligamento, mas agora suponha que eu gostaria de finalizar a execução em algum momento por algum motivo. Como posso fazer isso?

O problema que eu encontrei é que, olhando para top , vejo apenas o foo correspondente a "a.txt" . Eu posso terminar essa chamada de foo , mas então o foo correspondente a "b.txt" é chamado e então eu tenho que finalizar esse também, e assim por diante. Para dezenas ou centenas de arquivos de texto especificados no loop for , torna-se difícil terminar cada foo , um por um! Então, de alguma forma, eu preciso terminar o script de shell em si , não as chamadas particulares emitidas pelo script de shell.

Quando eu digito o comando

ps -u myusername

onde myusername é meu nome de usuário, recebo uma lista de processos que estou executando. Mas vejo dois IDs de processo diferentes chamados bash . Como sei qual desses processos, se houver, corresponde à minha chamada original nohup bash script.sh & ?

    
por Andrew 14.06.2013 / 21:19

3 respostas

9

Por padrão, ps não mostrará os parâmetros com os quais o programa foi chamado. As opções -f e -l mostrarão a chamada completa.

ps -fu username

resultará em uma saída semelhante a:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh
    
por 14.06.2013 / 21:35
11

Você tem algumas opções. Como seu processo está sendo executado em segundo plano, você pode usar jobs para encontrá-lo:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

Você também pode usar pkill para pesquisar na tabela de processos por uma correspondência de linha de comando; viz:

pkill -f script.sh
    
por 14.06.2013 / 21:31
1

A ps output (com, por exemplo, ps aux ) inclui o ID do processo pai. Mate o pai bash e seus filhos também serão encerrados.

Para uma visualização em ASCII da árvore de processos, tente pstree -p com alguns processos em segundo plano em execução.

    
por 15.06.2013 / 07:05