It's because of the design of the Python interpreter and interactive session.

Ctrl + C sends a signal, SIGINT, to the Python process, which the Python interpreter handles by raising the KeyboardInterrupt exception in the currently-running scope.

If the interpreter is running in an interactive session (i.e. by running python or python3 at the console), then the exception in the current function is printed and you return to the Python prompt. If the interpreter is running a script (e.g. by python3 my_script.py), then unless the KeyboardInterrupt is handled by the script, the whole program will stop when the exception is raised.

Answer from Andy J on askubuntu.com
🌐
GitHub
github.com › python › cpython › issues › 95737
Ctrl-c not behaving as expected · Issue #95737 · python/cpython
August 6, 2022 - Bug report ctrl-c does not raise a keyboard interrupt. Problem started when modifed VS 2022 installation to include windows 10 sdk from the visual studio installer. I have already tried to repair and reinstall python and restart my compu...
Author   ghost
Discussions

Ctrl+C not working when using input on Windows
Description Keyboard interrupt freezes but doesn't exit script. What steps will reproduce the problem? Use python code: while True: input() Type, and press return once or a few times. Press Ctrl-C ... More on github.com
🌐 github.com
18
October 5, 2017
Ctrl-C doesn't send SIGINT to python program launched with debugger
Extensive searching leads me to ... Code. In a nutshell, "Ctrl-C" should raise a KeyboardInterupt in a running python program. When run in a vscode-python terminal with python3 program.py, it works as expected. When launched via debugger, it does not and the program just keeps ... More on github.com
🌐 github.com
13
December 14, 2020
About ctrl C not working in terminal. - Apple Community
Because Docker or the Python program itself may be trapping and ignoring the Interrupt (ctrl-c). Try ctrl-\ and you may need more than one repetition to force the application to exit and an associated dialog to appear. ... Thanks you a lot, you save my lot of time. ... You are welcome. ... This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers. About ctrl C not ... More on discussions.apple.com
🌐 discussions.apple.com
Stopping Python using Ctrl + C - Stack Overflow
Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I have a Python script that uses threads and makes lots of HTTP requests. I think, while a HTTP request (using urllib2) is reading, it's blocking and not responding to Ctrl ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Python
bugs.python.org › issue43070
Issue 43070: Control keys stop working after pressing Ctrl-C Escape Enter - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide.
🌐
GitHub
github.com › spyder-ide › spyder › issues › 5401
Ctrl+C not working when using input on Windows · Issue #5401 · spyder-ide/spyder
October 5, 2017 - Ctrl+C not working when using input ... exit script. What steps will reproduce the problem? Use python code: while True: input() Type, and press return once or a few times....
Author   toonarmycaptain
🌐
GitHub
github.com › microsoft › debugpy › issues › 500
Ctrl-C doesn't send SIGINT to python program launched with debugger · Issue #500 · microsoft/debugpy
December 14, 2020 - [NOTE: If you suspect that your issue is related to the Microsoft Python Language Server (python.languageServer: 'Microsoft'), please download our new language server Pylance from the VS Code marketplace to see if that fixes your issue] ... When I "Start debugging" with "Python: Current file", "ctrl-c" at terminal, SIGINT is passed to python process and raises a KeyboardException wherever it is currently executing. The above works as expected when a program is run from the terminal with python3 program.py, but when launched with the debugger as above, SIGINT isn't passed to Python.
Author   alexwhittemore
🌐
Apple Community
discussions.apple.com › thread › 253354013
About ctrl C not working in terminal. - Apple Community
Because Docker or the Python program itself may be trapping and ignoring the Interrupt (ctrl-c). Try ctrl-\ and you may need more than one repetition to force the application to exit and an associated dialog to appear. ... Thanks you a lot, you save my lot of time.
🌐
Raspberry Pi Forums
forums.raspberrypi.com › board index › programming › python
Catching a Ctrl-C - Raspberry Pi Forums
sudo python3.7 programadddress.py & into .bashrc, my raspberry pi cheerfully runs the script upon booting up. Is it because of the "&" at the end? It is true, as you say, that it's not accepting keyboard interrupts. But it is running. ... Its running in the background and if you then continue in the shell then its the shell that gets the "ctrl+c" when you press it and not your program.
Find elsewhere
🌐
Python.org
discuss.python.org › python help
Making Python Script Exit Completely with One Ctrl+C - Python Help - Discussions on Python.org
December 7, 2023 - Dear Python community, I hope this message finds you in good health. I am reaching out to seek your assistance regarding an issue that I have been experiencing with one of my Python scripts that involves the use of libc…
🌐
Python
bugs.python.org › issue38428
Issue 38428: Can't gracefully ctrl+C multiprocessing pool on Python3 & Windows - Python tracker
October 10, 2019 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/82609
🌐
Python
bugs.python.org › issue1677
Issue 1677: Ctrl-C will exit out of Python interpreter in Windows - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/46018
🌐
JetBrains
youtrack.jetbrains.com › issue › PY-4840
Send signals (e.g. by CTRL-C) to an opened console
January 22, 2021 - {{ (>_<) }} This version of your browser is not supported. Try upgrading to the latest stable version. Something went seriously wrong
🌐
Vorpus
vorpus.org › blog › control-c-handling-in-python-and-trio
Control-C handling in Python and Trio — njs blog
This means that control-C won't work if your Twisted program runs away in an infinite loop that never yields to the event loop, and even if does work then any callback chains or coroutines that are in progress will get abruptly abandoned, but it will at least run any registered shutdown callbacks.
🌐
GitHub
github.com › zeromq › pyzmq › issues › 100
Ctrl-C doesn't kill python on windows · Issue #100 · zeromq/pyzmq
April 14, 2011 - Like the title says - python 2.7, pyzmq and zeromq are both 2.1.4. This simple code https://gist.github.com/920133 doesn't die when you hit ctrl-c in the terminal.
Author   SavageMessiah
🌐
Reddit
reddit.com › r/python › windows command line automation - ctrl-c question
r/Python on Reddit: Windows command line automation - Ctrl-C question
May 6, 2013 -

I have a question about sending "ctrl-c" type events to stdin on Windows. I googled around and even StackOverflow was full of dead ends.

Let's consider a simple program:

import subprocess

TSHARK_PATH = "C:\\Program Files\\Wireshark\\tshark.exe"
OUTPUT_FILE_NAME = "captured_packets.pcap"
OUTPUT_DIR = "C:\\captured_packets_dir\\"
INTERFACE_NO = "1" #as per "tshark -D"
PACKET_FILTER = "icmp" # just an example
OUTPUT_FILE_SIZE_LIMIT = "200" #in kB

# here we do some preparation

tshark = subprocess.Popen([TSHARK_PATH, "-i", INTERFACE_NO, "-b", "filesize:"+OUTPUT_FILE_SIZE_LIMIT, "-f", PACKET_FILTER, "-w", OUTPUT_DIR+OUTPUT_FILE_NAME])

# packet capturing is running, we do some other actions

tshark.terminate()

# do some post processing using captured files

Here is the problem:

  • If I do the same from console (manually) everything is fine -> but the Tshark is stopped by ctrl-c

  • If I do this from Python script (automatically) I get an "partial packet" error -> the Tshark is stopped by terminate()

Is there a way to send "ctrl-c" to the process using Subprocess? I know that Popen can be run with stdin=subprocess.PIPE, but simple write() won't do the trick.

Or maybe I'm doing this backwards and this is not the right solution to do this? I'm using Tshark because it's easier to use this tool for all the heavy lifting.

Windows seem to be rather unfriendly towards Python automation of command line tools.

Top answer
1 of 4
4

This works:

import subprocess
import time
import win32api
import win32con

proc = subprocess.Popen("ping -t localhost", stdin=subprocess.PIPE)
time.sleep(3) # just so it runs for a while

print "sending ctrl c"
try:
	win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT, 0)
	proc.wait()
except KeyboardInterrupt:
	print "ignoring ctrl c"

print "still running"

It sends ctrl-c to all processes that share the console of the calling process but then ignores it in the python process with an exception handler. You can't target the subprocess directly because that signal cannot be generated for process groups.

ctypes version

import subprocess
import time
import ctypes
proc = subprocess.Popen("ping -t localhost", stdin=subprocess.PIPE)
time.sleep(3) # just so it runs for a while

try:
	ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, 0)
	proc.wait()
except KeyboardInterrupt:
	print "ignoring ctrlc"
print "still running"

ctrl-break version

This can target the process specifically but with ping ctrl-break doesn't actually cause it to terminate. You may be able to use it with tshark though.

import subprocess
import time
import ctypes
proc = subprocess.Popen("ping -t localhost", stdin=subprocess.PIPE,
	creationflags=512) # CREATE_NEW_PROCESS_GROUP = 512
time.sleep(3) # just so it runs for a while

ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, proc.pid) # CTRL_BREAK_EVENT = 1
proc.wait()
2 of 4
2

On Unix, the terminate() functions sends SIGINT, which allows the process to clean up after itself before exiting, while the kill() method sends SIGKILL which ends it immediately. However on Windows both methods call the Windows API function TerminateProcess which straight up kills the process and does not allow cleanup, so tshark never gets a chance to write its files. See here and here.

I'm not much of a Windows expert, but have you tried os.kill(process.pid, signal.CTRL_C_EVENT)?

EDIT: Looking at the documentation for subprocess, it also looks like you need to create the process with the CREATE_NEW_PROCESS_GROUP flag to allow you to send signals to it. As an alternative to os.kill, there is also the slightly cleaner tshark.send_signal(signal.CTRL_C_EVENT).

🌐
Python
bugs.python.org › issue1195
Issue 1195: Problems on Linux with Ctrl-D and Ctrl-C during raw_input - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/45536
🌐
GitHub
github.com › python › cpython › issues › 104566
Ctrl+C doesn't work on Windows Powershell · Issue #104566 · python/cpython
May 16, 2023 - Bug report When I run the python3 -m http.server command in Powershell, I cannot stop the process by simple Ctrl+C keyboard shortcut, it does nothing. As far as I have found, it has been reported in numerous packages, so it is not actual...
Published   May 16, 2023
Author   Polda18
🌐
Python.org
discuss.python.org › python help
How to handle Ctrl-C on asyncio server and client programs - Python Help - Discussions on Python.org
May 31, 2023 - Hi community, When I Ctrl-C on terminal to kill the server, I get random error as following. I can still get different error, If I replace: asyncio.run(main()) with: loop = asyncio.get_event_loop() loop.run_until_complete(main()) When I Ctrl-C on server terminal, it does not terminate the program, it just disconnects one client instead.