Detener Python usando Ctrl + C


128

Tengo un script de Python que usa subprocesos y hace muchas solicitudes HTTP. Creo que lo que está sucediendo es que mientras una solicitud HTTP (usando urllib2) está leyendo, está bloqueando y no responde CtrlCpara detener el programa. ¿Hay alguna forma de evitar esto?


9
No sé por qué, pero al menos en OS X, el uso de Control + Backslash hace que termine y aparece un cuadro de diálogo de "caída de Python" ... extraño. No es realmente esa información útil, por lo tanto, es un comentario!
micmoo

3
En realidad funciona en todas las aplicaciones en la terminal ...
micmoo

1
David Beazley ha descrito cómo una interrupción Ctrl / C puede convertir una secuencia de comandos Python con subprocesos muli en un CPU hog. Se toca aquí ( stackoverflow.com/questions/990102/… ) con un enlace a la charla de Beazley.
Ned Deily

Respuestas:


189

En Windows, la única forma segura es usarlo CtrlBreak. ¡Detiene cada script de Python al instante!

(Tenga en cuenta que en algunos teclados, "Break" está etiquetado como "Pausa").


44
¿Qué es Break? ¿Cómo lo escribo?
u0b34a0f6ae

55
Debería haber un botón Pause_Break en su teclado
jonatron

18
¿Qué pasa si no hay? Estoy en una Macbook Intel, y no tiene un teclado con todas las funciones.
Bluu

53
En Linux deberías usar Ctrl-Shift- \
Michał Zieliński el

12
ctrl + Z no mata el script, solo lo oculta en segundo plano y lo suspende. Puede escribir fg para recuperarlo.
Shady Xu

84

Si presiona Ctrl+ cmientras se ejecuta un programa de Python, Python generará una KeyboardInterruptexcepción. Es probable que un programa que realiza muchas solicitudes HTTP tenga muchos códigos de manejo de excepciones. Si la exceptparte del bloque try- exceptno especifica qué excepciones debería detectar, capturará todas las excepciones, incluida la KeyboardInterruptque acaba de causar. Un programa de Python correctamente codificado hará uso de la jerarquía de excepciones de Python y solo capturará las excepciones derivadas 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

Si no puede cambiar el código (o necesita eliminar el programa para que sus cambios surtan efecto), puede intentar presionar Ctrl+ crápidamente. La primera de las KeyboardInterruptexcepciones eliminará su programa del trybloque y, con suerte, se KeyboardInterruptgenerará una de las excepciones posteriores cuando el programa esté fuera de un trybloque.


1
Esta es una gran respuesta para habilitar el "descanso" más común que es ctrl + c.
Xerion

53

Si se ejecuta en el shell de Python, use Ctrl+ Z, de lo contrario, ubique el pythonproceso y elimínelo.


25
^Z-> [1]+ Stopped -> kill %1para detener el trabajo n. ° 1 (o el trabajo% 1 como bash lo pone)
u0b34a0f6ae

23
Vale la pena agregar a la respuesta que Ctrl + Z simplemente detiene el proceso.
Matteo Italia

2
Para explicar lo anterior: pausar el proceso lo mantiene en la memoria y en su shell, simplemente evita que use recursos de la CPU. Archivos, sockets, todo sigue abierto y en uso. De hecho, escribir fglo traerá de vuelta.
RandomInsano

2
Ctrl+Zno es la forma correcta de detener un script de python y debe evitarse a menos que planee reanudar el proceso en pausa.
Josh Correia

33

El proceso de interrupción depende del hardware y del sistema operativo. Por lo tanto, tendrá un comportamiento muy diferente dependiendo de dónde ejecute su script de Python. Por ejemplo, en máquinas con Windows tenemos Ctrl+ C( SIGINT) y Ctrl+ Break( SIGBREAK).

Entonces, si bien SIGINT está presente en todos los sistemas y se puede manejar y capturar, la señal SIGBREAK es específica de Windows (y se puede deshabilitar en CONFIG.SYS ) y el BIOS realmente la maneja como un vector de interrupción INT 1Bh , por lo que esta clave Es mucho más poderoso que cualquier otro. Entonces, si está utilizando un sistema operativo con sabor * nix, obtendrá diferentes resultados dependiendo de la implementación, ya que esa señal no está presente allí, pero otros sí. En Linux puede verificar qué señales están disponibles para usted:

$ 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

Entonces, si desea captar la CTRL+BREAK señal en un sistema Linux, deberá verificar a qué señal POSIX han asignado esa clave. Las asignaciones populares son:

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

De hecho, hay muchas más funciones disponibles en Linux, donde la SysRqtecla (Solicitud del sistema) puede cobrar vida propia ...


19

Este post es viejo pero recientemente me encontré con el mismo problema de Ctrl+ Cno poner fin a los scripts de Python en Linux. Usé Ctrl+ \( SIGQUIT).


Aunque causará un volcado del núcleo, pero detuvo el script, gracias
ospider

17

Ctrl+ DDiferencia para Windows y Linux

Resulta que a partir de Python 3.6, el intérprete de Python maneja Ctrl+ de manera Cdiferente para Linux y Windows. Para Linux, Ctrl+ Cfuncionaría sobre todo como era de esperar, sin embargo en Windows Ctrl+ C mayormente no funciona especialmente si se está ejecutando Python de bloqueo de llamadas, como thread.joino en espera de la respuesta web. Sin embargo, funciona time.sleep. Aquí está la buena explicación de lo que está sucediendo en el intérprete de Python. Tenga en cuenta que Ctrl+ Cgenera SIGINT.

Solución 1: Use Ctrl+ Breako Equivalente

Use los métodos abreviados de teclado a continuación en la ventana de terminal / consola que generará SIGBREAKen el nivel inferior en el sistema operativo y finalizará el intérprete de Python.

Mac OS y Linux

Ctrl+ Shift+ \o Ctrl+\

Ventanas :

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

Solución 2: use la API de Windows

A continuación se presentan funciones prácticas que detectarán Windows e instalarán un controlador personalizado para Ctrl+ Cen la consola:

#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)

Puede usar arriba de esta manera:

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!

Solución 3: método de votación

No prefiero ni recomiendo este método porque consume innecesariamente el procesador y la energía afecta negativamente el rendimiento.

tiempo de importación de subprocesos de importación

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, en Ubuntu, tanto para Python 2.7 como para 3.6, presionar ctrl + cno se cierra sino que se muestra KeyboardInterrupt.
Rick

7

En Mac, presione Ctrl+ \para salir de un proceso de Python conectado a una terminal.


3

En una terminal mac / in:

  1. Mostrar inspector (clic derecho dentro de la ventana de terminal o Shell> Mostrar inspector)
  2. haga clic en el icono de Configuración arriba de "procesos en ejecución"
  3. elija de la lista de opciones en "Grupo de proceso de señal" (matar, terminar, interrumpir, etc.).

1
  • Obligar al programa a cerrar usando Alt + F4 (cierra el programa actual)
  • Spam el botón X en CMD para ex
  • Administrador de tareas (primero Windows + R y luego "taskmgr") y luego finalizar la tarea.

Esos pueden ayudar.


1

Puede abrir su administrador de tareas (ctrl + alt + delete, luego vaya al administrador de tareas) y busque Python en él y el servidor se llama (por ejemplo) _go_app (la convención de nomenclatura es: _language_app).

Si finalizo la tarea _go_app, finalizará el servidor, por lo que ir allí en el navegador dirá que "finalizó inesperadamente", también uso git bash, y cuando inicio un servidor, no puedo salir del servidor en el shell de bash con ctrl + c o ctrl + pausa, pero una vez que finalice la tarea de python (la que usa 63.7 mb), saldrá del script del servidor en bash y me permitirá usar el shell git bash. ingrese la descripción de la imagen aquí


1

Para el registro, lo que mató el proceso en mi Raspberry 3B + (ejecutando raspbian) fue Ctrl+ '. En mi teclado AZERTY francés, el toque 'también es el número 4.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.