Terminando um script de shell bash em execução em segundo plano

16

Costumo usar bashscripts de shell para executar comandos simples para muitos arquivos diferentes. Por exemplo, suponha que eu tenho o seguinte bashshell script, chamada script.sh, que executa o comando / programa fooem 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 levará muito tempo (horas ou dias, por exemplo). Por isso, gostaria de usar nohuppara 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 interrupções, mas agora suponha que eu gostaria de encerrar a execução em algum momento por algum motivo. Como posso fazer isso?

O problema que encontrei é que, olhando top, vejo apenas o foocorrespondente a "a.txt". Posso encerrar a foochamada, mas o foocorrespondente a "b.txt"é chamado e, em seguida, tenho que encerrar a chamada, e assim por diante. Para dezenas ou centenas de arquivos de texto especificados no forloop, torna-se difícil encerrar todos foo, um por um! Então, de alguma forma, eu preciso finalizar o próprio script de shell , não as chamadas específicas emitidas a partir do script de shell.

Quando digito o comando

ps -u myusername

Onde myusernameestá meu nome de usuário, recebo uma lista dos processos que estou executando. Mas vejo duas identificações de processo diferentes chamadas bash. Como sei qual desses processos, se houver, corresponde à minha chamada original nohup bash script.sh &?

Andrew
fonte
@ Andrew, os dois processos mostram nohup mencionado no comando? .... como alternativa, você pode tentar ps -aWu Andrew e verificar se você encontra uma única entrada longa com nohup .... isso ajuda?
Nitin
2
Como um aparte, sua citação é maluca. for s in a b c; do foo "$s".txt; done
tripleee
11
@NSD: Não, nohupjá estará longe quando você abrir uma lista de processos para ver o trabalho iniciado. Você pode olhar para a coluna "gentileza" na pssaída, mas as respostas aqui são mais úteis.
tripleee

Respostas:

9

Por padrão, psnão mostrará os parâmetros com os quais o programa foi chamado. As opções -fe -lambas mostrarão a chamada completa.

ps -fu username

resultará em uma saída parecida com:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh
j883376
fonte
2
Isso é moderadamente útil, mas não desambigua vários processos com os mesmos argumentos.
tripleee
11

Você tem algumas opções. Como seu processo está sendo executado em segundo plano, você pode usá jobs-lo 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 pkillpara procurar na tabela de processos uma correspondência de linha de comando; viz:

pkill -f script.sh
JRFerguson
fonte
1

A pssaída (com, por exemplo ps aux) inclui o ID do processo do pai. Mate o pai bashe seus filhos também serão extintos.

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

triplo
fonte