Skip to content
Advertisement

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.

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement