Bash: O que fazer quando o control-c não mata um processo, existe uma solução melhor para o botão on / off?

1

O título completo desta pergunta é:

Bash: O que fazer quando o control-c não mata um processo, devido ao fato de que o script contém um loop que chama outro processo: Existe uma solução melhor para o botão liga / desliga?

O título desta pergunta é bastante auto-explicativo, mas aqui estão algumas informações mais detalhadas:

Eu tenho um script bash em execução que chama outro programa. (Executa / executa outro programa.)

Este programa é um programa de ajuste de dados / curvas, que não pode ser interrompido com CTRL-C . Mas, lendo este postar , eu encontrado eu posso matá-lo com CTRL-\

Pensamentos Hipotéticos ...

Portanto, é possível apenas misturar o teclado, segurar a tecla CTRL e misturar a tecla \ , MAS e se você comprou um teclado mecânico realmente caro ontem e não tem dinheiro suficiente para comprar outro teclado barato que você está disposto a "mash" (porque você não quer usar qualquer uma dessas 10 ^ 6 teclas de pressionamento que você tem antes de seu novo teclado mecânico ficar desgastado), ou, alternativamente, não tenha tempo suficiente para encontrar seu teclado antigo em sua casa porque sua casa está extremamente desordenada (uma bagunça) ou porque há uma emergência como um incêndio em uma panela elétrica ocorrendo simultaneamente ...

Considere também que um loop está chamando esse programa de ajuste e talvez você esteja se encaixando em 1.000 arquivos de dados. Pressionar a tecla \ 1000 vezes levará muito tempo.

Pensamentos do hiperespaço ...

Ou mesmo; e se você cometeu um erro no script bash e está realmente executando um loop infinito?

O que você pode fazer para impedir que o script pai seja executado nessa situação? Você pode desconectar o computador, manter pressionado o botão liga / desliga por 10 segundos para desligá-lo ou jogá-lo no chip-pan para impedi-lo de funcionar, mas essas soluções parecem insensíveis devido à possível perda de dados que pode ocorrer. / p>

Em teoria, pode-se executar o monitor do sistema e talvez encerrar o processo bash, mas isso pode ser difícil de encontrar se você tiver muitos desses processos todos com o mesmo nome ... Além disso, você pode ter um único computador central , ou um computador multicore com N núcleos, executando N processos que estão todos tentando usar 100% da CPU. Ou talvez apenas 1 processo esteja usando mais do que os 4 GB de memória RAM que você tem e, portanto, o computador está extremamente lento por esse motivo ... Muito lento, pelo menos para executar o monitor do sistema por enquanto. A próxima melhor opção depois disso é pressionar CTRL-ALT-F1 e tentar fazer login como root e encontrar o pai agressor usando ps -A then kill PID ... Mas, novamente, isso pode levar muitos minutos do seu tempo se seu computador é tão carregado que está continuamente escrevendo para trocar.

SIG TERM exec cpu_broken.sh; reconvocar; limpar tela; clear thought_processes; continue ...

Existe uma solução melhor?

    
por user3728501 16.06.2015 / 17:41

3 respostas

2

Então, basicamente, você executa um script que torna tudo inacessível e deseja uma solução rápida e fácil para interrompê-lo. Uma alternativa ao powercycling é manter a tecla SYSRQ (é a mesma que a tecla PRTSC em muitos casos), e pressionar um por um R , E , I , S , U , B . Basicamente, essa é uma maneira segura de eliminar todos os processos em execução e reiniciar o sistema.

Alternativa para isso é fazer sudo nano /proc/sysrq-trigger , escrever b, nesse arquivo e salvar. O sistema irá reiniciar imediatamente

Mais informações: link

    
por Sergiy Kolodyazhnyy 16.06.2015 / 19:31
1

Você precisa matar todo o grupo de processos. O ID do grupo de processos (PGID) é o PID do processo que iniciou o grupo. Para eliminar o grupo de processos, você precisa encontrar o PID do processo que iniciou o grupo de processos, ou seja, o script ou comando que iniciou tudo. A sintaxe é:

kill -- -PGID

Por exemplo:

kill -- -1234

Aqui 1234 é o PGID (ID do grupo de processos).

Isso enviará SIGTERM para todos os processos no grupo de processos. Para enviar um sinal diferente, por ex. SIGKILL (9) faz:

kill -9 -1234

Como encontrar o PGID:

Você pode fazer:

ps -eo 'pid,ppid,pgid,cmd'

Isto irá ajustar o PID, o PPID (ID do processo pai), o PGID e o nome do processo.

Agora você pode usar grep ou qualquer outro método adequado para encontrar o PGID e, em seguida, eliminá-lo pelos métodos mencionados acima.

A razão pela qual eu fiz o comando para mostrar o PPID é porque você também pode tentar matar o processo baseado na correspondência PPID por pkill :

pkill -P PPID

Por exemplo:

pkill -P 6789

Usando este método, você precisa encontrar todos os processos pai (e filhos) e então matá-los, então, na minha opinião, matar toda a árvore de processos é uma maneira melhor se você quiser matar todos eles.

    
por heemayl 16.06.2015 / 21:17
1

Normalmente você pode usar top , htop ou similar para encontrar o processo e matá-lo (ou se você souber o nome ou PID do processo, você pode killall , pkill etc). Por exemplo, usando top , posso selecionar um script em execução no terminal e eliminá-lo pressionando k + Enter :

Se isto não funcionar, k + 9 + Enter deve usar o sinal SIGKILL. O SIGKILL solicita que o processo seja morto imediatamente, e não espera que o processo termine a limpeza de recursos, etc., como o SIGTERM faz. Ctrl + C um processo só envia SIGINT para interromper o processo, como o SIGTERM faz.

Usando o modo de exibição de árvore (pressione t ) no htop também, você pode determinar os processos pai de um script e matá-los para garantir que não continue o loop.

Veja também:

por Wilf 16.06.2015 / 20:35