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

14

Quando executo um comando ( makeem um projeto grande) a partir do shell, posso digitar Ctrl-Z para interromper o processo e retornar ao shell. Posteriormente, posso executar fgpara continuar o processo.

Estou tentando escrever um script de shell para automatizar isso (especificamente, para verificar a temperatura da CPU a cada poucos segundos e interromper o processo se estiver muito quente, pois 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 interrompeu (como ficou evidente pelo fato de ele continuar enviando saída para o terminal). Corri make &na linha de comando, enviei o SIGSTOP e verifiquei o status do processo com ps; foi listado como parado (e iniciado novamente quando enviei o SIGCONT), mas ainda estava vomitando a saída e aumentando minha temperatura central! Parar com Ctrl-Z nunca teve esse problema, mas não sei como fazer isso em um script.

O que diferencia o Ctrl-Z kill -STOPe como posso obter o comportamento do primeiro em um script de shell?

Taymon
fonte
E sim, makeestá sendo executado recursivamente. Na verdade, acho que vai vários níveis de profundidade.
Taymon

Respostas:

12

O que diferencia o Ctrl-Z kill -STOPe como posso obter o comportamento do primeiro em um script de shell?

CTRL-Znormalmente envia SIGTSTP (que pode ser bloqueado) e - além de outras coisas - os shells geralmente redefinem tty 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 o PID de um trabalho retomado fg).

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

peterph
fonte
4

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

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

O set -mpermite "controle de trabalho", que está desativado por scripts dentro padrão. Eu acho que deve funcionar para o seu caso de uso, embora as pessoas pareçam pensar que é uma má ideia em geral .

sourcejedi
fonte
4

Você pode enviar um sinal para todos os processos em um grupo de processos se especificar um valor 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, 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:

  • Ctrl-Z realmente envia TSTP, que pode ser bloqueado.
  • STOP não pode ser bloqueado.
Jurij
fonte
A abordagem PGID não funcionou, e produziu a seguinte linha de produção: /usr/local/bin/myscript: line 38: kill: (-10202) - No such process. Os processos em segundo plano continuaram em execução. Eu não acho que a killallabordagem funcionaria porque alguns dos subprocessos parecem ser she não make.
Taymon
Parece que o processo para o qual você está enviando o sinal já terminou. Os subprocessos nomeados sh são gerados pelo make. No seu caso de make e muitos subprocessos, o melhor seria provavelmente obter PIDs de todas as crianças e PARAR todas elas.
Jurij
Acabou funcionando quando eu o fiz manualmente a partir do shell, mas não em um script de shell. Eu estou pensando que isso ocorre porque quando eu fiz isso manualmente, o PID raiz (do qual os outros herdaram seu PGID) foi o do primeiro makecomando, mas quando eu fiz isso a partir do script, o PID raiz foi do próprio script de shell .
Taymon 22/03
1

Ctrl+ Cé usado para matar um processo com sinal SIGINT; por outras palavras, é uma morte educada .

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

No entanto, quando um processo é suspenso, podemos retomar novamente fg (retomar em primeiro plano) e bg (retomar em segundo plano) , mas não consigo retomar um processo morto, que é a diferença entre usar Ctrl+ C& Ctrl+ Z.

Como visualizar o processo suspenso?

Quando você tem vários comandos suspensos, para tê-los listados, você usa o jobscomando e a saída será:

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

Como matar um processo suspenso em segundo plano?

Usando o killcomando:

kill %nonde n é o número do trabalho (aquele em colchetes da saída de postos de trabalho), então eu quero matar gato: kill %1.

antzshrek
fonte