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()
Related
Context:
I have a running python script. It contains many os.system("./executableNane") calls in a loop.
If I press ctrl + C, it just stops the execution of the current ./executableNane and passes to the next one.
Question:
How to stop the execution of the whole script and not only the execution of the current executable called?
Please note that I have read carefully the question/answer here but even with kill I can kill the executable executableNane but not the whole script (that I cannot find using top).
The only way I have to stop the script (without reboot the system) is to continue to press ctrl + C in a loop as well until all the tests are completed.
You can use subprocess and signal handlers to do this. You can also use subprocess to receive and send information via subprocess.PIPE, which you can read more about in the documentation.
The following should be a basic example of what you are looking to do:
import subprocess
import signal
import sys
def signal_handler(sig, frame):
print("You pressed Ctrl+C, stopping.")
print("Signal: {}".format(sig))
print("Frame: {}".format(frame))
sys.exit(123)
# Set up signal handler
signal.signal(signal.SIGINT, signal_handler)
print("Starting.")
while True:
cmd = ['sleep', '10']
p = subprocess.Popen(cmd)
p.wait()
if p.returncode != 0:
print("Command failed.")
else:
print("Command worked.")
The other solution to the question (by #Quillan Kaseman) is much more elegant compared with the solution I have found. All my problems are solved when I press Ctrl + Z instead of Ctrl + C.
Indeed, I have no idea why with Z works and with C does not. (I will try to look for some details later on).
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?
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.
When I'm in a python application (the python shell, for instance), pressing ctrl + \ results in
>>> Quit (core dumped)
Why is this, and how can I avoid this?
It is very inconvenient if application bails out whenever I press ctrl + \ by accident.
CTRL-\ is the Linux key that generates the QUIT signal. Generally, that signal causes a program to terminate and dump core. This is a feature of UNIX and Linux, wholly unrelated to Python. (For example, try sleep 30 followed by CTRL-\.)
If you want to disable that feature, use the stty command.
From the Linux command line, before Python starts:
stty quit undef
The python module signal is convenient to deal with this.
import signal
# Intercept ctrl-c, ctrl-\ and ctrl-z
def signal_handler(signal, frame):
pass
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGQUIT, signal_handler)
signal.signal(signal.SIGTSTP, signal_handler)
Just add handlers to the signal that (in this case) do nothing.
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.