Python Signals, Timeouts and Process Termination
An automation script that can hang for ever is worse than one that fails, because nobody finds out. This guide covers the timeout that stops a child, the timeout that leaves it running, escalating from terminate to kill, what a negative return code means, and how to catch SIGTERM so your own script finishes the item it is on rather than dying in the middle of it.
OS and Process Automation Guide 21 of 39 Intermediate
- Control nodeUbuntu 26.04 LTS
- Python3.14.4
- requests2.34.2
- paramiko5.0.0
- TimeAbout 20 min
signal.Signals as an enum needs Python 3.5, and signal.raise_signal 3.8. Signal handlers only run in the main thread of the main interpreter, which has always been true.
- pytest9.1.1
- PyYAML6.0.3
- boto3 / botocore1.43.78
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| RUNNER01 | 192.168.0.27 | Ubuntu 26.04 LTS | Control node - every script in this path runs here | 2 Core | 4 GB | 50 GB |
This guide includes
Use this because a script that can hang for ever is worse than one that fails. This matters because a timeout on Popen.wait does not stop the child - it only stops you waiting for it.
- timing out a child with
subprocess.run, then meeting the timeout that does not stop it - sending
terminatethenkill, and reading what a return code says about a signal - handling a signal in your own script
- seeing what a bare
kill -9costs you, and which signals cannot be caught - enforcing a timeout on yourself, not only on children
Before you start
-
A child that takes too long
-
The timeout that does not stop the child
-
terminate, then kill
-
What a return code says about a signal
-
Handling a signal in your own script
-
And what a bare kill -9 costs you
-
The one signal you cannot catch
-
A timeout you enforce on yourself