Como parar um loop bash while em execução em segundo plano?


23

Comecei um loop while da seguinte maneira:

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

Observe o &.

Eu pensei que quando eu matei o terminal, esse loop while iria parar. Mas ainda está indo. Faz horas que eu matei a sessão do terminal.

Como faço para parar este loop while?

Respostas:


38

eu comecei

while true; do yad; sleep 60; done &

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

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

Vamos ter uma visão geral dos processos em execução, com ps fjxas ú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 yadcomo um subprocesso de /bin/bash, se eu fechar, yadele muda sleep 60na saída de ps. Se a exibição em árvore for muito confusa, você também poderá procurar a saída da seguinte maneira 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, o primeiro sendo o PPID, o ID do processo pai e o segundo o PID, o ID do próprio processo. É por isso que 9411aparece 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 bashsubshell que queremos matar e acabamos de descobrir seu PID, então agora tudo o que resta é simples

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

e o subshell irritante se foi para sempre.

1 : A notação como, em grep "[y]ad"vez de simplesmente, grep yadimpede que o greppróprio processo apareça na lista de resultados.


Se você ainda tiver o terminal aberto

bashfornece a variável $!, que “se expande para a identificação do processo da tarefa mais recentemente colocada em segundo plano”, para que o seguinte acabe com o processo mais recente em segundo plano:

kill $!

Se não for o processo mais recente, é possível obter uma lista dos trabalhos em execução com a jobssaída incorporada, exemplo:

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

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

kill %1  # or
kill %-

e matar o sleep 10trabalho suspenso :

kill %2  # or
kill %+  # or
kill %

5

Eu preciso observar que quando você fecha o terminal onde inseriu esse 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 matar o programa que você deixou em execução em segundo plano, causado pelo &final do comando, é o seguinte:

  1. Abra um novo shell e execute echo $$para anotar seu PID (ID do processo) atual, para não matar 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 ps -ef | grep $SHELLcomando para descobrir quais programas estão executando um shell.
  3. Observe a segunda coluna da esquerda e observe o valor numérico que difere do echo $$resultado acima; este é o PID que você deseja matar.
  4. Execute o kill -SIGTERM <pid>comando, onde <pid>está o valor numérico que você identificou na etapa # 3
  5. Confirme se o programa não está mais em execução, repetindo a etapa 2

Você também pode reiniciar sua sessão ou seu computador, mas as opções acima permitirão evitar isso.


2
Você também pode usar toppara interromper o processo pressionando k, inserindo o PID e pressionando enter duas vezes.
Luk3yx # 9/18

-1

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


-3

Geralmente bg para o fundo fg para o primeiro plano. Se você usar & symbol, use fg, ele exibirá o programa atual em execução. Pressione Ctrl + C para matar.


3
Usar bg/ fgnão funcionará quando o terminal for desconectado bash. Não seria possível reconectar usando reptyrporque bashpossui processos filhos ( sleep).
Xiota

Ele fechou o terminal porque ele matará esse processo. Então, da próxima vez, ele usará o fg para fechar o programa. Simples
Curioso

@Curious é a próxima vez. Mas a OP está perguntando sobre esse momento.
RonJohn
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.