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, 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

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

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.