Os.kill Signals not being received correctly, alternative is kill -SIGUSR1 command

The script is sending the signal before the child process has a chance to actually set a handler for SIGUSR1. Try the following instead:

import sys
import signal
import subprocess
import time

if sys.platform == 'linux':
    def wait_until_ready(pid, sig, timeout=1):
        deadline = time.monotonic() + timeout
        while time.monotonic() < deadline:
            mask = 0
            with open('/proc/{}/status'.format(pid)) as f:
                for line in f.readlines():
                    if line[:7].lower() == 'sigcgt:':
                        mask = int(line[7:], 16)
                        break
            if mask & (1 << (sig - 1)):
                break
else:
    def wait_until_ready(pid, sig, timeout=1):
        time.sleep(timeout)

cmd = ['tar', '-xpf', sys.argv[2], '-C', sys.argv[1], '--totals=SIGUSR1']
with subprocess.Popen(cmd, stderr=subprocess.PIPE, text=True) as p:
    try:
        wait_until_ready(p.pid, signal.SIGUSR1)
        while p.poll() is None:
            p.send_signal(signal.SIGUSR1)
            time.sleep(1)
            print(p.stderr.readline().strip())
    except KeyboardInterrupt:
        p.terminate()

On Linux, this waits until the child process sets a handler for SIGUSR1. On other POSIX platforms (macOS, BSD, etc), it simply waits for a second because I couldn’t be bothered to look up how to implement it properly.

2 Likes