Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python subprocess.CalledProcessError: returned non-zero exit status 2

Tags:

python

linux

#!/usr/bin/env python
# encoding: utf-8

import re
import subprocess
import time
import json


def get_temperatures(disks):
    sensors = subprocess.check_output(["sensors"])
    temperatures = {match[0]: float(match[1]) for match in re.findall("^(.*?)\:\s+\+?(.*?)°C", 
                                            sensors, re.MULTILINE)}
    for disk in disks:
        output = subprocess.check_output(["smartctl", "-A", disk])
        temperatures[disk] = int(re.search("Temperature.*\s(\d+)\s*(?:\([\d\s]*\)|)$", 
                                            output, re.MULTILINE).group(1))
    return temperatures


def main():
    while True:
        print json.dumps(get_temperatures(("/dev/sda2", "/dev/sdb1")))
        time.sleep(20)


if __name__ == '__main__':
    main()

This is small script to monitor temperatures in Python, using smartmontools and lm-sensors. But when i try to run it i have a error

subprocess.CalledProcessError: Command '['smartctl', '-A', '/dev/sda2']' returned non-zero exit status 2

But when i try this command manually in terminal they work great.

Some info:

uname -a 
Linux LME 4.0.0-040000-generic #201504121935 SMP Sun Apr 12 23:36:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
like image 999
Konstantin Monahov Avatar asked Apr 23 '15 13:04

Konstantin Monahov


2 Answers

A CalledProcessError will be raised if any non-zero exit code is returned by your called process. On the command line, you should echo $? to get the last return code and see if it really does return 2. I suspect it will.

If that is okay in your python code, you can except the CalledProcessError and get any information from within its attributes especially the output attribute. (Look up this error in the python docs for more information.)

Example:

import subprocess
output = None
try:
    output = subprocess.check_output(["smartctl", "-A", "/dev/sda2"])
except subprocess.CalledProcessError as e:
    output = e.output
like image 150
BlackVegetable Avatar answered Oct 17 '22 20:10

BlackVegetable


Return code of 2 from smartctl means it failed to open the device. Make sure that the user who is running the Python code has permission to open all of the disks you want it to check.

From the RETURN VALUES section of smartctl's man page:

Bit 1: Device open failed, or device did not return an IDENTIFY DEVICE structure

So I suspect this is really a permissions problem. I verified this on my system. If I run subprocess.check_output( [ 'smartctl', '-A', '/dev/sda2' ] ) I get the error with it returning 2, but if I run subprocess.check_output( [ 'sudo', 'smartctl', '-A', '/dev/sda2' ] ) it works and I see the output of the command.

like image 26
Eric Renouf Avatar answered Oct 17 '22 21:10

Eric Renouf