user1625344
user1625344

Reputation: 313

Killing a background process launched with python sh

I have a compiled program I launch using python sh as a background process. I want to run it for 20 seconds, then kill it. I always get an exception I can't catch. The code looks like


        cmd = sh.Command('./rtlogger')
        try:
            p = cmd('config.txt', _bg=True, _out='/dev/null', _err='/dev/null', _timeout=20)
            p.wait()
        except sh.TimeoutException:
            print('caught timeout')

I have also tried to use p.kill() and p.terminate() after catching the timeout exception. I see a stack trace that ends in SignalException_SIGKILL. I can't seem to catch that. The stack trace references none of my code. Also, the text comes to the screen even though I'm routing stdout and stderr to /dev/null.

The program seems to run OK. The logger collects the data but I want eliminate or catch the exception. Any advice appreciated.

Upvotes: 0

Views: 71

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155363

_timeout for the original invocation only applies when the command is run synchronously, in the foreground. When you run a command asynchronously, in the background, with _bg=True, you need to pass timeout to the wait call instead, e.g.:

    cmd = sh.Command('./rtlogger')
    try:
        p = cmd('config.txt', _bg=True, _out='/dev/null', _err='/dev/null')
        p.wait(timeout=20)
    except sh.TimeoutException:
        print('caught timeout')

Of course, in this case, you're not taking advantage of it being in the background (no work is done between launch and wait), so you may as well run it in the foreground and leave the _timeout on the invocation:

    cmd = sh.Command('./rtlogger')
    try:
        p = cmd('config.txt', _out='/dev/null', _err='/dev/null', _timeout=20)
    except sh.TimeoutException:
        print('caught timeout')

You don't need to explicitly kill or terminate the child process; the _timeout_signal argument is used to signal the child on timeout (defaulting to signal.SIGKILL). You can change it to another signal if SIGKILL is not what you desire, but you don't need to call kill/terminate yourself either way; the act of timing out sends the signal for you.

Upvotes: 1

Related Questions