Quando executo um comando ( make
em um projeto grande) a partir do shell, posso digitar Ctrl-Z para interromper o processo e retornar ao shell. Posteriormente, posso executar fg
para 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 -STOP
e como posso obter o comportamento do primeiro em um script de shell?
fonte
make
está sendo executado recursivamente. Na verdade, acho que vai vários níveis de profundidade.Respostas:
CTRL-Z
normalmente 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 retomadofg
).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.
fonte
Você não quer parar o
make
processo; você deseja interromper omake
processo e todos os seus processos filhos. Aposto que make estava sendo executado recursivamente.Você pode tentar
set -m
e usar em%1
vez de"$subpid"
.O
set -m
permite "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 .fonte
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.
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
:A diferença entre Ctrl + Z e kill -STOP:
fonte
/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 akillall
abordagem funcionaria porque alguns dos subprocessos parecem sersh
e nãomake
.make
comando, mas quando eu fiz isso a partir do script, o PID raiz foi do próprio script de shell .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) ebg
(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
jobs
comando e a saída será:Como matar um processo suspenso em segundo plano?
Usando o
kill
comando:kill %n
onde n é o número do trabalho (aquele em colchetes da saída de postos de trabalho), então eu quero matar gato:kill %1
.fonte