Qual é a diferença entre Ctrl-Z e kill -STOP?

13

Quando executo um comando ( make em um projeto grande) do shell, posso digitar Ctrl-Z para interromper o processo e retornar ao shell. Posteriormente, posso executar fg para continuar o processo.

Eu estou tentando escrever um script de shell para automatizar isso (especificamente, verificar a temperatura da minha CPU a cada poucos segundos e parar o processo se ficar muito quente, já que meu computador está sujeito a superaquecimento). Minha primeira tentativa funcionou assim (simplificada):

make &
subpid="$!"

sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"

sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"

wait "$subpid"

Infelizmente, isso não funcionou; O envio do SIGSTOP para o processo não o fez parar (como ficou evidente ao continuar enviando a saída para o terminal). Eu executei make & na linha de comando, enviei SIGSTOP e verifiquei o status do processo com ps ; foi listado como interrompido (e reiniciado quando enviei o SIGCONT), mas ele ainda estava emitindo a saída e aumentando a temperatura do meu núcleo! Pará-lo com Ctrl-Z nunca teve esse problema, mas não sei como fazer isso em um script.

O que torna o Ctrl-Z diferente de kill -STOP e como posso obter o comportamento do primeiro em um script de shell?

    
por Taymon 20.03.2013 / 20:43

4 respostas

12

What makes Ctrl-Z different from kill -STOP, and how can I get the behavior of the former in a shell script?

CTRL-Z geralmente envia SIGTSTP (que pode ser bloqueado), e - além de outras coisas - os shells frequentemente são redefinidos para um estado salvo anteriormente nessas ocasiões. Mais importante, no entanto, o grupo de processos do terminal de controle é definido para o PID do shell (e, em seguida, novamente para um PID de um job retomado com fg ).

Voltar ao seu problema original: usar uma escala de frequência dependente da temperatura, como, por exemplo, Cpufreqd pode ser um martelo melhor para a sua unha.

    
por 20.03.2013 / 23:13
4

Você não quer parar o processo make ; você quer parar o make process e todos os seus processos filhos. Aposto que o make estava sendo executado recursivamente.

Você pode tentar set -m e usar %1 em vez de "$subpid" .

O set -m ativa o "controle do trabalho", que está desativado por padrão dentro dos scripts. Acho que deve funcionar para o seu caso de uso, embora pessoas parece pensar que é uma má ideia em geral .

    
por 20.03.2013 / 21:06
4

Você pode enviar um sinal para todos os processos em um grupo de processos se você especificar um valor de PID negativo - PGID de um líder de sessão.

kill -STOP -"$subpid"

Nota: Para executar um programa em uma nova sessão, use setsid make . Mas no seu caso eu acho que não é necessário. No entanto, se o make for executado recursivamente, cada instância do make poderá ser seu próprio líder (não tenho certeza disso).

Outra opção poderia ser usar killall :

killall -STOP make

A diferença entre Ctrl + Z e kill -STOP:

  • O Ctrl-Z envia o TSTP, que pode ser bloqueado.
  • O STOP não pode ser bloqueado.
por 20.03.2013 / 22:50
1

Ctrl + C é usado para matar um processo com sinal SIGINT , por outras palavras, é um educado kill .

Ctrl + Z é usado para suspender um processo enviando-lhe o sinal SIGSTP , que é como um sinal de sono, que pode ser desfeito e o processo pode ser retomado novamente.

No entanto, quando um processo é suspenso, podemos retomá-lo novamente por fg (currículo em primeiro plano) e bg (retomar em segundo plano) , mas não pode retomar um processo eliminado, isto é, uma diferença entre usar Ctrl + C & Ctrl + Z .

Como visualizar processo suspenso?

Quando você tem vários comandos suspensos, para listá-los, use o comando jobs e a saída será:

[1]-  Stopped                 cat
[2]+  Stopped                 vi

Como matar um processo suspenso em segundo plano?

Usando o comando kill :

kill %n onde n é o número do trabalho (aquele entre colchetes da saída de jobs), então eu quero matar cat: kill %1 .

    
por 22.09.2017 / 06:55