Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to register a signal handler for a subprocess?

Adding a signal handler, e.g.

#!/usr/bin/python

import subprocess as sp
import signal
import time

def child_handler(sig, frame):
    print("SIGINT child received")

def handler(sig, frame):
    print("SIGINT received")

def preexec():
    print("entering preexec")
    signal.signal(signal.SIGINT, child_handler)
    #signal.signal(signal.SIGINT, signal.SIG_IGN)
    print("leaving preexec")

def signal_sending():
    signal.signal(signal.SIGINT, handler)
    p = sp.check_call(["bash", "process.sh"], preexec_fn=preexec)

if __name__ == "__main__":
    signal_sending()

with process.sh

#!/bin/sh

i=0

while [ 1 ]; do
sleep 0.1;
echo $i
i=$((i + 1))
done

doesn't work because CtrlC interrupts the child process (only SIGINT received is printed), but both SIGINT received and SIGINT child received should be printed and the child continue to run.

Adding signal.SIG_IGN leaves the child untouched, but that not sufficient since I need to write a custom handler for the child.

I don't care if I have to use python 2.7 or 3.x to acchieve that. I'm using Linux 4.3.

like image 932
Kalle Richter Avatar asked Sep 20 '25 01:09

Kalle Richter


1 Answers

The bash process replaces the forked python process and therefore it can't run a Python callback. SIG_IGN works for SIGINT because it survives the exec() call.

If you want some Python code to run when Ctrl+C is pressed; put it in the handler() (the signal handler in the parent). Or trap the corresponding signal in bash and run python subprocess on the signal in process.sh.

like image 126
jfs Avatar answered Sep 22 '25 16:09

jfs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!