Python fails to quit when using Ctrl-C in Powershell/Command Prompt, and instead gives out a "KeyboardInterrupt" string.
Recently I've reinstalled Windows 10. Before the reinstall Ctrl-C quit python (3.5/2.7) fine, with no output.
Does anyone know why this has started happening? Whether it's just a simple setting?
The only difference I can think of is I'm now on python 3.6. Ctrl-D works in Bash on Ubuntu on Windows, and Ctrl-C works fine in an activated anaconda python2 environment for quitting python.
I had this issue with Windows 10 Pro Build 18363 and Python 3.8.1. I was running some python scripts and was unable to stop some with CTRL + C, but CTRL + BREAK worked every time. The Windows Docs had this to say:
The CTRL+C and CTRL+BREAK key combinations receive special handling by console processes. By default, when a console window has the keyboard focus, CTRL+C or CTRL+BREAK is treated as a signal (SIGINT or SIGBREAK) and not as keyboard input...
CTRL+BREAK is always treated as a signal, but an application can change the default CTRL+C behavior in two ways that prevent the handler functions from being called:
The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT input mode for a console's input buffer, so CTRL+C is reported as keyboard input rather than as a signal.
When SetConsoleCtrlHandler is called with NULL and TRUE values for its parameters, the calling process ignores CTRL+C signals. Normal CTRL+C processing is restored by calling SetConsoleCtrlHandler with NULL and FALSE values. This attribute of ignoring or not ignoring CTRL+C signals is inherited by child processes, but it can be enabled or disabled by any process without affecting existing processes.
Thus, CTRL + C seems to be a SIGINT and its actions can be modified by the program you are running. It seems that Python on Windows has been coded in such a way that CTRL + C is being processed as keyboard input rather than the SIGINT we are expecting. Fortunately for me I have the CTRL + BREAK keys on my keyboard and this works every time.
For those of you who dont have BREAK on your keyboard, you can use the Windows On Screen virtual Keyboard.
Press win key + r to open the run application program.
Type oskand press ok
On the virtual keyboard, press ctrl + ScrLk and this should kill the program.
This stack thread has some other methods you can try if ctrl + ScrLk doesnt work on the virtual keyboard.
You can type
CTRL + Z,
then hit ENTER to exit python from powershell.
Powershell Screenshot
This is a bug that recently appeared in Windows 10 Insider build 15002.
A work around is to change the Mapped Keys from Ctrl C to something like Ctrl K
If you are not familar how to do this, You can look up or at stty -a
You can run this command on each bash session that will map your Terminate to Ctrl + K
stty intr \^k
As a TEMP solution you could include this in your Bashrc so it is executed on each new session
This bug has been reported already on Github #1569
In my case, I found out that right ctrl + c does the trick in anaconda3 powershell - so no remapping necessary - I'm on Windows 10.
That worked like magic
If you have a laptop with Fn key, tap:
Ctrl + Fn + S
Source:
https://www.dell.com/community/Laptops-General-Read-Only/break-key-alternative/td-p/3826467
When you press Control C, a KeyboardInterrupt exception is thrown. If it isn't stopping the code, the best thing to do is to add a try statement into your code which catches KeyboardInterrupt
try:
....
except KeyboardInterrupt:
exit()
The code is just off the top of my head so sorry if something is wrong.
EDIT: Ctrl Break or on some keyboards Ctrl Pause instantly stops python code apparently.
Hitting Esc button on the upper corner of the keyboard seems to work for me on Windows-7, inside Spyder with numpy running, for Python 3.+
It broke the infinite ...: on an erroneous syntax in the interactive script
When I used to press Ctrl-C, python was quit normally without any output.
I really don't remember when I can quit python with Ctrl + C. In my memory, Ctrl + C always give me KeyboardInterrupt.
I also counldn't find an answer explaining why Ctrl + C can't quit the python in shell. FYI, Ctrl + D and Ctrl + \ can quit python for different reasons. See #Gilles's answer here. https://superuser.com/questions/169051/whats-the-difference-between-c-and-d-for-unix-mac-os-x-terminal
But I think how to handle Ctrl + C is merely a decision of the program. Yes, I think it totally depends on how the program would like to handle it. See the example I write below.
test.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static void ctrlC_Handler(int sig){
if(sig == SIGINT){
printf("(:KeyboardInterrupt:)\n");
printf(">>>");
signal(SIGINT, ctrlC_Handler);
}
}
static void welcome(){
printf("Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15)\n");
printf("[GCC 7.3.0] on linux2\n");
printf("Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n");
printf(">>>");
fflush(stdout);
}
int main(){
welcome();
signal(SIGINT, ctrlC_Handler);
for(;;){
pause();
}
return 0;
}
compile it with gcc test.c and execute it ./a.out. Try pressing Ctrl + C, you can see at least it mimics the behaviour(output) of the python program when you input Ctrl + C.
So, in my opinion, it's nothing special, but a human/programmer/author's decision on how to handle it.
Related
In my current windows 10 version (10.0.18362) it does not work to cancel a python program with Ctrl + C when running in CMD.
I dont know if it has to do with it, I just want to state that the main Thread has finished but another thread is running when I try to hit Ctrl + C.
What can I do to get a KeyboardInterrupt Exception that I urgently need in order to close the socket that is in use?
Currently whenever I press CTRL + Z on a lengthy script I was given, it immediately terminates the script ([1+] stopped(SIGTSTP) ./test.py) which is what I want, but it also leaves the python2 process running (when I type ps to look at processes), which forces me to use killall -9 python2, which I do not want to do every time. Is there a way to immediately terminate a script that doesn't leave the python2 process running in the background?
There is no SIGTSTP currently in the code that I see but I did try using the following code with no luck. It didn't even exit the script when I pressed CTRL + Z.
def handler(signum, frame):
sys.exit("CTRL+Z pressed. Exiting Test")
signal.signal(signal.SIGTSTP, handler)
SIGSTP is a signal to suspend a process, it sounds like you want to terminate a process. You can try sending Ctrl-C or CTRL-D instead, which should send a SIGINT signal.
I believe you could also try CTRL-\ which sends SIGQUIT.
Use Ctrl + C. SIGTSTP suspends the process, hence why it keeps it open, but does not terminate it.
(Note: On a Linux terminal use Ctrl + \, otherwise use Ctrl + C or Ctrl + D)
Or just use sys.exit()
How do I capture Ctrl+C in line and exit the program as user enters it. I am using Python 3.7.3 on IPython 7.4.0 on spyder 3.3.3 on windows 64 bit machine with 8 GB RAM.
The most important thing is that when I run this program on windows powershell it works, this is happening only with spyder.
I tried using threads, KeyboardInterrupt, etc. but nothing works. I also saw lots of post regarding this but none is useful. Thing is that everytime python fails to capture Ctrl + C.
while True:
line = input()
if ('line contains Ctrl+C')
break
print(line)
print("Exiting")
I expect that after pressing Ctrl + C , program will print "Exiting" and stop execution.
The main thing there is what happens when you press Ctrl+C. It just stops. That being said, you might be able to except KeyboardInterrupt. Have you tried this?
import sys
try:
#Code Stuff Goes Here
except KeyboardInterrupt:
print(Exiting...)
sys.exit()
This might be a silly question, but as I can't find an answer, I have to ask it.
In interactive python I want to process a message which i get with:
>>> message = sys.stdin.readlines()
Everything works fine, but... how to stop it from getting an input and make it save into message variable? Stopping with ctrl+c stops whole process so there is no input to be saved anywhere. I guess there's an easy answer I just can't find...
For UNIX based systems (Linux, Mac):
Hello, you can type : Ctrld
Ctrld closes the standard input (stdin) by sending EOF.
Example :
>>> import sys
>>> message = sys.stdin.readlines()
Hello
World
My
Name
Is
James
Bond
# <ctrl-d> EOF sent
>>> print message
['Hello\n', 'World\n', 'My\n', 'Name\n', 'Is\n', 'James\n', 'Bond\n']
For Windows :
To send EOF on Windows, type Ctrlz
This is an old question but it needs an update about Windows and different keyboard layouts.
If neither CTRL + Z nor CTRL + D ** work for you on Windows and and you're wandering what is going on do this:
check if you are using default english keyboard layout
if you do have different, non-default keyboard layout try switching keyboard setting to English in language bar, then try pressing ctrl + z after changes
if you're still confused look at the screen, what appears in command line when you press ctrl + z. What symbol do you see? When I was pressing ctrl + z I was seeing this: ^Y, and when by mistake I pressed ctrl + y I've seen this ^Z, i pressed enter and the input was taken, EOF sent.
This is somewhat strange and counterintuitive. I changed keys layout some time ago to include polish characters, but all the common keys are left unchanged, z still maps to z when I use the keyboard normally, normally ctrl + z does nothing in my keyboard, so I shouldn't be changed. But apparently in cmd it works differently, in order to have default link between ctrl and z I have to switch to default layout, or use control y to sent EOF.
On windows simply do CTRL+Z and press enter
Use CTRL-D.
message = sys.stdin.readlines()
abc
def
<CTRL-D>
# message == ['abc\n', 'def\n']
If you are a Mac user, please use command + D. It works!
I tested that in VS code terminal.
After using this command:
for line in stdin:
I input many lines of data. Keep pressing Enter does not work now.
Solution:
Press Ctrl + Z, you will see ^Z in the terminal.
Then you have to press Enter to finish.
I have a python script that uses threads and makes lots of HTTP requests. I think what's happening is that while a HTTP request (using urllib2) is reading, it's blocking and not responding to CtrlC to stop the program. Is there any way around this?
On Windows, the only sure way is to use CtrlBreak. Stops every python script instantly!
(Note that on some keyboards, "Break" is labeled as "Pause".)
Pressing Ctrl + c while a python program is running will cause python to raise a KeyboardInterrupt exception. It's likely that a program that makes lots of HTTP requests will have lots of exception handling code. If the except part of the try-except block doesn't specify which exceptions it should catch, it will catch all exceptions including the KeyboardInterrupt that you just caused. A properly coded python program will make use of the python exception hierarchy and only catch exceptions that are derived from 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
If you can't change the code (or need to kill the program so that your changes will take effect) then you can try pressing Ctrl + c rapidly. The first of the KeyboardInterrupt exceptions will knock your program out of the try block and hopefully one of the later KeyboardInterrupt exceptions will be raised when the program is outside of a try block.
If it is running in the Python shell use Ctrl + Z, otherwise locate the python process and kill it.
The interrupt process is hardware and OS dependent. So you will have very different behavior depending on where you run your python script. For example, on Windows machines we have Ctrl+C (SIGINT) and Ctrl+Break (SIGBREAK).
So while SIGINT is present on all systems and can be handled and caught, the SIGBREAK signal is Windows specific (and can be disabled in CONFIG.SYS) and is really handled by the BIOS as an interrupt vector INT 1Bh, which is why this key is much more powerful than any other. So if you're using some *nix flavored OS, you will get different results depending on the implementation, since that signal is not present there, but others are. In Linux you can check what signals are available to you by:
$ 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
So if you want to catch the CTRL+BREAK signal on a linux system you'll have to check to what POSIX signal they have mapped that key. Popular mappings are:
CTRL+\ = SIGQUIT
CTRL+D = SIGQUIT
CTRL+C = SIGINT
CTRL+Z = SIGTSTOP
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP
In fact, many more functions are available under Linux, where the SysRq (System Request) key can take on a life of its own...
Ctrl+D Difference for Windows and Linux
It turns out that as of Python 3.6, the Python interpreter handles Ctrl+C differently for Linux and Windows. For Linux, Ctrl+C would work mostly as expected however on Windows Ctrl+C mostly doesn't work especially if Python is running blocking call such as thread.join or waiting on web response. It does work for time.sleep, however. Here's the nice explanation of what is going on in Python interpreter. Note that Ctrl+C generates SIGINT.
Solution 1: Use Ctrl+Break or Equivalent
Use below keyboard shortcuts in terminal/console window which will generate SIGBREAK at lower level in OS and terminate the Python interpreter.
Mac OS and Linux
Ctrl+Shift+\ or Ctrl+</kbd>
Windows:
General: Ctrl+Break
Dell: Ctrl+Fn+F6 or Ctrl+Fn+S
Lenovo: Ctrl+Fn+F11 or Ctrl+Fn+B
HP: Ctrl+Fn+Shift
Samsung: Fn+Esc
Solution 2: Use Windows API
Below are handy functions which will detect Windows and install custom handler for Ctrl+C in 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)
You can use above like this:
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!
Solution 3: Polling method
I don't prefer or recommend this method because it unnecessarily consumes processor and power negatively impacting the performance.
import threading
import time
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
This post is old but I recently ran into the same problem of Ctrl+C not terminating Python scripts on Linux. I used Ctrl+\ (SIGQUIT).
On Mac press Ctrl+\ to quit a python process attached to a terminal.
Capture the KeyboardInterrupt (which is launched by pressing ctrl+c) and force the exit:
from sys import exit
try:
# Your code
command = input('Type your command: ')
except KeyboardInterrupt:
# User interrupt the program with ctrl+c
exit()
On a mac / in Terminal:
Show Inspector (right click within the terminal window or Shell >Show Inspector)
click the Settings icon above "running processes"
choose from the list of options under "Signal Process Group" (Kill, terminate, interrupt, etc).
Forcing the program to close using Alt+F4 (shuts down current program)
Spamming the X button on CMD for e.x.
Taskmanager (first Windows+R and then "taskmgr") and then end the task.
Those may help.
You can open your task manager (ctrl + alt + delete, then go to task manager) and look through it for python and the server is called (for the example) _go_app (naming convention is: _language_app).
If I end the _go_app task it'll end the server, so going there in the browser will say it "unexpectedly ended", I also use git bash, and when I start a server, I cannot break out of the server in bash's shell with ctrl + c or ctrl + pause, but once you end the python task (the one using 63.7 mb) it'll break out of the server script in bash, and allow me to use the git bash shell.
For the record, what killed the process on my Raspberry 3B+ (running raspbian) was Ctrl+'. On my French AZERTY keyboard, the touch ' is also number 4.