Home > database >  Python: subprocess distinguish between killed and terminated process
Python: subprocess distinguish between killed and terminated process

Time:09-15

I have a python program which call another python program using subprocess.run, the called python program in turns call an executable using subprocess.run.

Following a simple example

a.py

#!/usr/bin/env python3
import subprocess

res = subprocess.run(['./b.py'])

retcode = res.returncode

if retcode > 0:
    print(f'a.py: Errored, retcode: {retcode}')
elif retcode < 0:
    print(f'a.py: Killed, retcode: {retcode}')
else:
    print(f'a.py: Completed, retcode: {retcode}')

b.py

#!/usr/bin/env python3
import subprocess
import sys

res = subprocess.run(['./c.sh'])
retcode = res.returncode
print(f"b.py: process exited with {retcode}")
sys.exit(retcode)

c.sh

#!/bin/bash
sleep 300

If I run a.py and then kill -9 <c.sh pid> I receive the following output

$ ./a.py       
b.py: process exited with -9
a.py: Errored, retcode: 247

What I want to achieve instead is to be able to tell from a.py that the c.sh script was killed, that is, I expect the following output:

$ ./a.py   
b.py: process exited with -9
a.py: Killed, retcode: -9    

As far as I understood the problem lies in the sys.exit(retcode) instruction where something like -9%6 is performed and so I'm unable to tell if c.sh was killed or errored.

How can I detect the difference?

Thanks

CodePudding user response:

https://tldp.org/LDP/abs/html/exitcodes.html The signal haves special meaning, greater than 128, lower or equal to 255. You can detect the difference with this information.

CodePudding user response:

From the documentation for sys.exit:

The optional argument arg can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero is considered “successful termination” and any nonzero value is considered “abnormal termination” by shells and the like. Most systems require it to be in the range 0-127, and produce undefined results otherwise. Some systems have a convention for assigning specific meanings to specific exit codes, but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors and 1 for all other kind of errors.

You can't just pass the -9 code to sys.exit(). What you can do is make a function within module b.py and call that from a.py. Script a.py can then check for the return number of b and print the appropriate message. a.py should check the retcode of subprocess b only to check whether b terminated without errors.

  • Related