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, "-C", sys.argv, "--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
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.killpg. I tried both, and I think
os.killis the intended method, but I can’t be sure.
- Spawning a
-SIGUSR1to select the signal, and the process PID given from the
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?