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.