Fermare Python usando ctrl + c


128

Ho uno script Python che usa i thread e fa molte richieste HTTP. Penso che ciò che sta accadendo sia che mentre una richiesta HTTP (usando urllib2) sta leggendo, sta bloccando e non risponde CtrlCper fermare il programma. C'è un modo per aggirare questo?


9
Non so perché, ma almeno su OS X, l'utilizzo di Control + Backslash provoca la chiusura e si ottiene una finestra di dialogo "Python crash" ... strano. Non proprio quelle informazioni utili, quindi è un commento!
micmoo,

3
In realtà funziona su tutte le applicazioni nel Terminale ...
micmoo,

1
David Beazley ha descritto come un interrupt Ctrl / C può trasformare uno script Python a thread multipli in un porco di CPU. È toccato qui ( stackoverflow.com/questions/990102/… ) con un link al discorso di Beazley.
Ned Deily,

Risposte:


189

Su Windows, l'unico modo sicuro è usare CtrlBreak. Ferma immediatamente ogni script di Python!

(Si noti che su alcune tastiere, "Break" è etichettato come "Pausa".)


4
Che cosa è Break? Come lo scrivo?
u0b34a0f6ae,

5
Dovrebbe esserci un pulsante Pause_Break sulla tastiera
jonatron,

18
E se non ci fosse? Sono su un Macbook Intel e non ha una tastiera con funzionalità complete.
Bluu,

53
Su Linux dovresti usare Ctrl-Shift- \
Michał Zieliński il

12
ctrl + Z non uccide lo script, lo nasconde solo in background e lo sospende. Puoi digitare fg per richiamarlo.
Shady Xu,

84

Premendo Ctrl+ cmentre è in esecuzione un programma Python, Python genererà KeyboardInterruptun'eccezione. È probabile che un programma che effettua molte richieste HTTP abbia un sacco di codice di gestione delle eccezioni. Se la exceptparte del blocco try- exceptnon specifica quali eccezioni dovrebbe catturare, catturerà tutte le eccezioni inclusa quella KeyboardInterruptche hai appena causato. Un programma python correttamente codificato farà uso della gerarchia delle eccezioni python e rileverà solo le eccezioni da cui derivano Exception.

#This is the wrong way to do things
try:
  #Some stuff might raise an IO exception
except:
  #Code that ignores errors

#This is the right way to do things
try:
  #Some stuff might raise an IO exception
except Exception:
  #This won't catch KeyboardInterrupt

Se non riesci a modificare il codice (o devi eliminare il programma per rendere effettive le modifiche), puoi provare a premere Ctrl+ crapidamente. La prima delle KeyboardInterrupteccezioni eliminerà il programma dal tryblocco e si spera che una delle KeyboardInterrupteccezioni successive verrà sollevata quando il programma si trova all'esterno di un tryblocco.


1
Questa è un'ottima risposta per abilitare la "pausa" più comune che è ctrl + c.
Xerion,

53

Se è in esecuzione nella shell di Python usa Ctrl+ Z, altrimenti individua il pythonprocesso e uccidilo.


25
^Z-> [1]+ Stopped -> kill %1per interrompere il lavoro n. 1 (o il lavoro% 1 come dice bash)
u0b34a0f6ae

23
Vale la pena aggiungere alla risposta che Ctrl + Z mette in pausa il processo.
Matteo Italia,

2
Per approfondire quanto sopra: mettere in pausa il processo lo mantiene in memoria e nella shell, gli impedisce semplicemente di utilizzare le risorse della CPU. File, socket, tutto è ancora aperto e in uso. In effetti, la digitazione fglo riporterà indietro.
RandomInsano,

2
Ctrl+Znon è il modo corretto per interrompere uno script Python e dovrebbe essere evitato a meno che non si pianifichi di riprendere il processo sospeso.
Josh Correia,

33

Il processo di interruzione dipende dall'hardware e dal sistema operativo. Quindi avrai un comportamento molto diverso a seconda di dove esegui il tuo script Python. Ad esempio, su macchine Windows abbiamo Ctrl+ C( SIGINT) e Ctrl+ Break( SIGBREAK).

Quindi mentre SIGINT è presente su tutti i sistemi e può essere gestito e catturato, il segnale SIGBREAK è specifico di Windows (e può essere disabilitato in CONFIG.SYS ) ed è realmente gestito dal BIOS come vettore di interruzione INT 1Bh , motivo per cui questa chiave è molto più potente di qualsiasi altro. Quindi, se stai usando un sistema operativo basato su * nix, otterrai risultati diversi a seconda dell'implementazione, poiché quel segnale non è presente lì, ma altri lo sono. In Linux puoi controllare quali segnali sono disponibili per te:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
31) SIGUSR2     32) SIGRTMAX

Quindi, se vuoi catturare il CTRL+BREAK segnale su un sistema Linux, dovrai controllare a quale segnale POSIX hanno mappato quella chiave. Le mappature popolari sono:

CTRL+\     = SIGQUIT 
CTRL+D     = SIGQUIT
CTRL+C     = SIGINT
CTRL+Z     = SIGTSTOP 
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP

In effetti, molte altre funzioni sono disponibili sotto Linux, dove il SysRqtasto (Richiesta di sistema) può assumere una vita propria ...


19

Questo post è vecchio ma di recente ho riscontrato lo stesso problema di Ctrl+ Cnon terminare gli script Python su Linux. Ho usato Ctrl+ \( SIGQUIT).


Anche se causerà un dump principale, ma ha fermato la sceneggiatura, grazie
ospider

17

Ctrl+ DDifferenza per Windows e Linux

Si scopre che a partire da Python 3.6, l'interprete Python gestisce Ctrl+ in modo Cdiverso per Linux e Windows. Per Linux, Ctrl+ Cfunzionerebbe principalmente come previsto, tuttavia su Windows Ctrl+ C per lo più non funziona soprattutto se Python sta eseguendo il blocco di chiamate come thread.joino in attesa di risposta web. Funziona time.sleepcomunque. Ecco la bella spiegazione di cosa sta succedendo nell'interprete Python. Si noti che Ctrl+ Cgenera SIGINT.

Soluzione 1: utilizzare Ctrl+ Breako equivalente

Utilizzare le scorciatoie da tastiera sottostanti nella finestra del terminale / console che genererà SIGBREAKa un livello inferiore nel sistema operativo e terminerà l'interprete Python.

Mac OS e Linux

Ctrl+ Shift+ \o Ctrl+\

Windows :

  • Generale: Ctrl+Break
  • Dell: Ctrl+ Fn+ F6o Ctrl+ Fn+S
  • Lenovo: Ctrl+ Fn+ F11o Ctrl+ Fn+B
  • HP: Ctrl+ Fn+Shift
  • Samsung: Fn+Esc

Soluzione 2: utilizzare l'API di Windows

Di seguito sono riportate utili funzioni che rileveranno Windows e installeranno il gestore personalizzato per Ctrl+ Cnella console:

#win_ctrl_c.py

import sys

def handler(a,b=None):
    sys.exit(1)
def install_handler():
    if sys.platform == "win32":
        import win32api
        win32api.SetConsoleCtrlHandler(handler, True)

Puoi usare sopra in questo modo:

import threading
import time
import win_ctrl_c

# do something that will block
def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()

#install handler
install_handler()

# now block
t.join()

#Ctrl+C works now!

Soluzione 3: metodo di polling

Non preferisco né raccomando questo metodo perché consuma inutilmente processore e potenza influendo negativamente sulle prestazioni.

import threading tempo di importazione

def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()
while(True):
    t.join(0.1) #100ms ~ typical human response
# you will get KeyboardIntrupt exception

No, su Ubuntu, sia per Python 2.7 che 3.6, premendo ctrl + cnon si esce ma si mostra KeyboardInterrupt.
Rick,

7

Su Mac premi Ctrl+ \per uscire da un processo Python collegato a un terminale.


3

Su un mac / nel Terminale:

  1. Mostra ispettore (fai clic con il pulsante destro del mouse nella finestra del terminale o Shell> Mostra ispettore)
  2. fai clic sull'icona Impostazioni sopra "processi in esecuzione"
  3. scegliere dall'elenco di opzioni in "Signal Process Group" (Kill, terminate, interrupt, ecc.).

1
  • Forzare la chiusura del programma usando Alt + F4 (arresta il programma corrente)
  • Spam del pulsante X su CMD per es
  • Taskmanager (prima Windows + R e poi "taskmgr"), quindi termina l'attività.

Quelli possono aiutare.


1

Puoi aprire il tuo task manager (ctrl + alt + delete, quindi andare al task manager) e cercarlo in python e il server viene chiamato (per esempio) _go_app (la convenzione di denominazione è: _language_app).

Se termino l'attività _go_app, il server termina, quindi andando lì nel browser lo dirà "inaspettatamente terminato", utilizzo anche git bash e quando avvio un server, non riesco a uscire dal server nella shell di bash con ctrl + c o ctrl + pause, ma una volta terminata l'attività python (quella che usa 63,7 mb), uscirà dallo script del server in bash e mi permetterà di usare la shell git bash. inserisci qui la descrizione dell'immagine


1

Per la cronaca, ciò che ha interrotto il processo sul mio Raspberry 3B + (in esecuzione raspbian) è stato Ctrl+ '. Sulla mia tastiera francese AZERTY, il tocco 'è anche il numero 4.

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.