Como parar um bash enquanto o loop é executado em segundo plano?

19

Eu iniciei um loop while da seguinte forma:

while true; do {command}; sleep 180; done &

Observe o & .

Eu pensei que quando eu matei o terminal, esse loop pararia. Mas ainda está indo. Já faz horas que matei a sessão do terminal.

Como eu paro esse loop while?

    
por Saqib Ali 09.05.2018 / 07:57

4 respostas

35

eu comecei

while true; do yad; sleep 60; done &

e fechou o terminal para testá-lo, agora tenho o mesmo problema.

Se você já fechou o terminal, você iniciou o loop

Vamos obter uma visão geral dos processos em execução com ps fjx , as últimas linhas da minha máquina lidas

 2226 11606 11606 19337 ?           -1 S     1000   0:00  \_ /bin/bash
11606 22485 11606 19337 ?           -1 S     1000   0:00  |   \_ sleep 10
 2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
 9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad
    1  2215  2215  2215 ?           -1 Ss    1000   0:00 /lib/systemd/systemd --user
 2215  2216  2215  2215 ?           -1 S     1000   0:00  \_ (sd-pam)

Você pode ver yad como um subprocesso de /bin/bash , se eu fechar yad , ele será alterado para sleep 60 na saída de ps . Se a visão em árvore é muito confusa, você também pode pesquisar a saída como segue 1 :

ps fjx | grep "[y]ad"  # or respectively
ps fjx | grep "[s]leep 60"

As linhas de saída começam com dois números, sendo o primeiro o PPID, o ID do processo pai e o segundo o PID, o ID do próprio processo. É por causa disso que 9411 aparece nas duas linhas aqui:

2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad

Esse é o subgrupo bash que queremos matar e acabamos de descobrir o seu PID, então agora tudo o que resta é simples

kill 9411  # replace 9411 with the PID you found out!

e a subchave irritante se foi para sempre.

1 : A notação como grep "[y]ad" em vez de simplesmente grep yad impede que o processo grep apareça na lista de resultados.

Se você ainda tiver o terminal aberto

bash fornece a variável $! , que "se expande para o ID do processo do trabalho colocado mais recentemente em segundo plano", portanto, o seguinte apenas mata o processo mais recente em segundo plano:

kill $!

Se não for o processo mais recente, só poderá obter uma lista de tarefas em execução com a saída de exemplo jobs builtin:

[1]-  Running                 while true; do
    yad; sleep 60;
done &
[2]+  Stopped                 sleep 10

Existem dois trabalhos na lista de trabalhos, para eliminar um deles, você pode acessá-lo com o número do trabalho ou com os atalhos % , %+ (“trabalho atual”) e %- (“trabalho anterior”) ), por exemplo para matar o loop em execução no fundo que você poderia fazer

kill %1  # or
kill %-

e para matar o trabalho sleep 10 suspenso:

kill %2  # or
kill %+  # or
kill %
    
por dessert 09.05.2018 / 08:47
5

Eu preciso notar que quando você fecha o terminal onde você inseriu o comando, o subcomando deveria ter morrido junto com ele. Tentando reproduzir isso mostrou esse comportamento.

Agora, supondo que você realmente esteja em uma situação em que isso não aconteceu, uma maneira de acabar com o programa que você deixou executando em segundo plano, que foi causada pelo & no final do comando, é o seguinte:

  1. Abra um novo shell e execute echo $$ para anotar seu PID (ID do processo) atual, para que você não mate sua própria sessão.
  2. Identifique o PID do programa que você acha que ainda está em execução; você pode fazer isso usando o comando ps -ef | grep $SHELL para descobrir quais programas estão executando um shell.
  3. Anote a segunda coluna da esquerda e anote o valor numérico que difere do seu resultado echo $$ acima; este é o PID que você quer matar.
  4. Execute o comando kill -SIGTERM <pid> , em que <pid> é o valor numérico identificado na etapa 3
  5. Confirme que o programa não está mais sendo executado repetindo a etapa 2

Você também pode reiniciar sua sessão ou seu computador, mas os itens acima permitirão evitar isso.

    
por code_dredd 09.05.2018 / 08:05
-1

O & fará com que o terminal crie um novo processo e faça seu código rodar dentro dele. Portanto, seu código se torna independente do processo do terminal. Mesmo se você fechar o terminal, o novo processo no qual seu código está sendo executado não será interrompido. Então, remova & ou ps -aux , localize seu processo e mate kill (process id) .

    
por Dr4ke the b4dass 09.05.2018 / 23:56
-3

Normalmente bg para plano de fundo fg para primeiro plano. Se você usar o símbolo & , use fg e mostrará o programa atual em execução. Pressione Ctrl + C para matar.

    
por Curious 09.05.2018 / 08:54