How python subprocess can detect a negative exit code? How to force it return 0 instead?

1.1k views Asked by At

I'm using pkill to send USR2 signal to suricata by python subprocess as below:

#!/usr/bin/python3

script_command='pkill -SIGUSR2 -f /usr/bin/suricata'
exit_status = subprocess.call(script_command, env=self.config_environment, shell=True)

the result is: exit_status = -12

When I executed on terminal:

pkill -SIGUSR2 -f /usr/bin/suricata
echo $?

the result is: 0

As I understand the document said at https://docs.python.org/3/library/subprocess.html#subprocess.CompletedProcess.returncode

Does Python detect return code of pkill process or suricata process is 12?

How can I bypass this mechanism and force subprocess.call return 0 when pkill send USR2 to suricata successfully and negative exit code corresponding to pkill process's feedback?

1

There are 1 answers

6
AKX On

The documentation you've linked says

A negative value -N indicates that the child was terminated by signal N (POSIX only).

This implies that the process run by subprocess.call() was killed by SIGUSR2 (since SIGUSR2 is 12).

Since you're using shell=True, there will be a process with the command line sh -c '... suricata', which will be matched by pkill -f (since -f means The pattern is normally only matched against the process name. When -f is set, the full command line is used.).

You may want to do

ret = subprocess.call([
  shutil.which("pkill"),
  "-SIGUSR2",
  "-f",
  "/usr/bin/suricata",
])

to avoid the additional shell process.

Better yet, you could use e.g. psutil to find the Suricata process and kill it.

EDIT

From the comments:

However pkill -SIGUSR2 -F /var/run/suricata.pid is enough

If you have a pidfile at hand, you don't need pkill for anything...

import os
import signal

with open("/var/run/suricata.pid", "r") as pidfile:
  pid = int(pidfile.read().strip())
  os.kill(pid, signal.SIGUSR2)