Qual è la differenza tra Ctrl-Z e kill -STOP?


14

Quando eseguo un comando ( makesu un grande progetto) dalla shell, posso digitare Ctrl-Z per interrompere il processo e tornare alla shell. Successivamente, posso eseguire fgper continuare il processo.

Sto provando a scrivere uno script di shell per automatizzare questo (in particolare, per controllare la temperatura della mia CPU ogni pochi secondi e interrompere il processo se fa troppo caldo, poiché il mio computer è soggetto a surriscaldamento). Il mio primo tentativo ha funzionato in questo modo (semplificato):

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"

Sfortunatamente, questo non ha funzionato; l'invio di SIGSTOP al processo non lo ha messo in pausa (come reso evidente dal suo continuo invio dell'output al terminale). Ho eseguito make &dalla riga di comando, inviato SIGSTOP e verificato lo stato del processo ps; è stato elencato come interrotto (e ricominciato quando ho inviato SIGCONT), ma stava ancora vomitando uscita e aumentando la mia temperatura interna! Fermarlo con Ctrl-Z non ha mai avuto questo problema, ma non so come farlo in uno script.

Cosa differenzia Ctrl-Z da kill -STOPe come posso ottenere il comportamento del primo in uno script di shell?


E sì, makeviene eseguito in modo ricorsivo. In effetti, penso che vada a diversi livelli di profondità.
Taymon,

Risposte:


12

Cosa differenzia Ctrl-Z da kill -STOPe come posso ottenere il comportamento del primo in uno script di shell?

CTRL-Zdi solito invia SIGTSTP (che può essere bloccato) e, a parte altre cose, le shell spesso riportano tty a uno stato precedentemente salvato in queste occasioni. Ancora più importante, tuttavia, il gruppo di processi del terminale di controllo è impostato sul PID della shell (e quindi nuovamente su un PID di un lavoro ripreso con fg).

Torna al tuo problema originale: l'uso di un ridimensionamento di frequenza dipendente dalla temperatura come ad esempio Cpufreqd potrebbe essere in realtà un martello migliore per il tuo chiodo.


4

Non vuoi interrompere il makeprocesso; vuoi interrompere il makeprocesso e tutti i suoi processi figlio. Scommetto che make è stato eseguito in modo ricorsivo.

Puoi provare set -m, quindi utilizzare %1invece di "$subpid".

Il set -mpermette "il controllo dei job", che è fuori dagli script all'interno di default. Penso che dovrebbe funzionare per il tuo caso d'uso, anche se la gente sembra pensare che sia una cattiva idea in generale .


4

È possibile inviare un segnale a tutti i processi in un gruppo di processi se si specifica un valore PID negativo - PGID di un leader di sessione.

kill -STOP -"$subpid"

Nota: per eseguire un programma in una nuova sessione, utilizzare setsid make. Ma nel tuo caso penso che non sia necessario. Tuttavia, se make viene eseguito in modo ricorsivo, ogni istanza di make potrebbe essere il proprio leader (non ne sono sicuro).

Un'altra opzione potrebbe essere quella di utilizzare killall:

killall -STOP make

La differenza tra Ctrl + Z e kill -STOP:

  • Ctrl-Z in realtà invia TSTP, che può essere bloccato.
  • STOP non può essere bloccato.

L'approccio pgid non ha funzionato, e ha prodotto la seguente riga di output: /usr/local/bin/myscript: line 38: kill: (-10202) - No such process. I processi in background hanno continuato a essere eseguiti. Non credo che l' killallapproccio funzionerebbe perché alcuni dei sottoprocessi sembrano essere shpiuttosto che make.
Taymon,

Sembra che il processo a cui stai inviando il segnale sia già terminato. I sottoprocessi di nome sh vengono generati da make. Nel tuo caso di make e di molti sottoprocessi, il migliore sarebbe probabilmente ottenere PID di tutti i bambini e fermarli tutti.
Jurij

Alla fine ha funzionato quando l'ho fatto manualmente dalla shell, ma non in uno script di shell. Penso che ciò sia dovuto al fatto che quando l'ho fatto manualmente, il PID root (da cui gli altri hanno ereditato il loro PGID) era quello del primo makecomando, ma quando l'ho fatto dallo script, il PID root era dallo script shell stesso .
Taymon,

1

Ctrl+ CÈ usato per uccidere un processo con il segnale SIGINT, da altre parole si tratta di un educato uccidere .

Ctrl+ Z viene utilizzato per sospendere un processo inviandogli il segnale SIGSTP , che è come un segnale di sospensione , che può essere annullato e il processo può essere ripreso di nuovo.

Tuttavia, quando un processo viene sospeso, possiamo riprenderlo nuovamente da fg (riprendi in primo piano) e bg (riprendi in background) , ma non riesco a riprendere un processo interrotto, questa è una differenza tra l'utilizzo di Ctrl+ C& Ctrl+ Z.

Come visualizzare il processo sospeso?

Quando si hanno più comandi sospesi, per averli elencati, si utilizza il jobscomando e l'output sarà:

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

Come interrompere un processo sospeso in background?

Usando il killcomando:

kill %ndove n è il numero di posti di lavoro (quello tra parentesi quadre dall'uscita posti di lavoro), quindi voglio uccidere cat: kill %1.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.