subprocess.check_output of service state on Remote

80 views Asked by At

I want to check the status of <SERVICE> on QEMU instance (standard connection is ssh [email protected]).

When I do

sshpass -p none ssh -o StrictHostKeyChecking=no [email protected] -t 'systemctl is-active <SERVICE>'

I got expected output:

failed

If I try to use subprocess.check_output for the same as

subprocess.check_output("sshpass -p none ssh -o StrictHostKeyChecking=no [email protected] -t 'systemctl is-active <SERVICE>'", shell=True, encoding='utf8', stderr=subprocess.DEVNULL)

I got

Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.8/subprocess.py", line 415, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.8/subprocess.py", line 516, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command 'sshpass -p none ssh -o StrictHostKeyChecking=no [email protected] -t 'systemctl is-active <SERVICE>'' returned non-zero exit status 3.

But if I use the same code-line with any other command, e.g.

 subprocess.check_output("sshpass -p none ssh -o StrictHostKeyChecking=no [email protected] -t 'echo $PATH'", shell=True, encoding='utf8', stderr=subprocess.DEVNULL)

I got expected output:

'/usr/bin:/bin:/usr/sbin:/sbin\n'

So why subprocess.check_output doesn't work correctly with systemctl?

2

There are 2 answers

0
DonnyFlaw On

I got the service status by replacing check_output method with run as

subprocess.run("sshpass -p none ssh -o StrictHostKeyChecking=no [email protected] -t 'systemctl is-active <SERVICE>'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).stdout

but that looks more like a workaround since check_output should be used specifically for getting the command output and run is general method to execute commands...

Update

Also getstatusoutput works as

subprocess.getstatusoutput("sshpass -p none ssh -o StrictHostKeyChecking=no [email protected] -t 'systemctl is-active <SERVICE>'")

However, it returns exitcode along with the status

(3, 'failed\nConnection to 192.168.7.2 closed.')

so required output should be parsed additionaly

0
tripleee On

check_output checks that the command succeeds; if the service is not running, the command fails. So running without the check is precisely what you want here.

For the record, subprocess.check_output(cmd) is basically equivalent to subprocess.run(cmd, check=True, text=True, capture_output=True).stdout

You want to avoid the shell=True; see Actual meaning of 'shell=True' in subprocess

result = subprocess.run(
    ["sshpass", "-p", "none",
     "ssh", "-o", "StrictHostKeyChecking=no",
     "[email protected]", "-t",
     f"systemctl is-active {SERVICE}"],
     capture_output=True, text=True, encoding='utf8',
     stderr=subprocess.DEVNULL).stdout