I’m trying to use the os.kill, Popen.send_signal, or otherwise some kind of pure-python implementation of sending a signal to a process. Unfortunately, none of them work, and instead, I spawn a kill
process to do it for me with Popen.
You can read my original issue on StackOverflow here, but someone just downvoted it and I have my doubts it will be answered by the bag of dicks at SO, and I’ve rewritten my latest progress in this topic here.
Here’s my code, you should be able to run this (I am on Linux Pop!_OS) without install. Developed on Python 3.7.
import os
import subprocess
import signal
import time
import sys
# Define the command to execute
command = ["tar", "-xpf", sys.argv[2], "-C", sys.argv[1], "--totals=SIGUSR1"]
# Start the subprocess
print(' '.join(command))
process = subprocess.Popen(command, preexec_fn=os.setsid, stderr=subprocess.PIPE)
try:
while True:
# Ping the subprocess with SIGUSR1 signal
# NOTWORK: process.send_signal(signal.SIGUSR1)
# NOTWORK: os.killpg(os.getpgid(process.pid), signal.SIGUSR1)
subprocess.Popen(["kill", "-SIGUSR1", str(process.pid)])
print(process.stderr.readline().decode("utf-8").strip())
# print(process.stdout.readline().decode("utf-8").strip())
# Wait for a specified interval
time.sleep(1.9) # Adjust the interval as needed
except KeyboardInterrupt:
# Handle Ctrl+C to gracefully terminate the script
process.terminate()
# Wait for the subprocess to complete
process.wait()
For a bit of context, I found out that tar
allows you to query progress reports on it by sending SIGUSR1 signals to it. You can confirm this yourself by running pkill -USR1 tar
in the CLI after starting a tar
process with --totals=USR1
.
You can see my three different styles of sending signals above:
- Popen.send_signal - One would believe this should work just fine, but after inspecting the source code, I am inclined to believe it might never work.
-
os.kill
andos.killpg
. I tried both, and I thinkos.kill
is the intended method, but I can’t be sure. - Spawning a
kill
process with-SIGUSR1
to select the signal, and the process PID given from thesubprocess
instance.
Only the third option works.
Additionally, the other two options kill the process, the return code being based on the signal: SIGUSR1 gives -10
, SIGUSR2 is -12
, and SIGHUP is -2
. This is documented based on a program’s default behavior for signal handling.
So, what gives?