16
#!/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
Georg Plaz
6,1265 gold badges45 silver badges66 bronze badges
asked Apr 23, 2015 at 13:10
6
  • 1
    What do you mean "they work great?" What is their exit code when they return? Commented Apr 23, 2015 at 13:13
  • if i type smartctl -A /dev/sda in terminal, this work perfectly Commented Apr 23, 2015 at 17:21
  • And if you run echo $? right after, does it print 0? Commented Apr 23, 2015 at 17:22
  • Yes, just 0, you have any idea? Commented Apr 23, 2015 at 17:34
  • Are you running both as the same user? Perhaps the user running the Python does not have permission to open /dev/sda2? Commented Apr 23, 2015 at 17:39

2 Answers 2

14

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
answered Apr 23, 2015 at 13:16
Sign up to request clarification or add additional context in comments.

3 Comments

➜ ~ echo $? 1 I change code like you say and now i have AttributeError: 'NoneType' object has no attribute 'group'
Interesting that you are getting different return values. Regardless, your NoneType error is almost certainly from getting a return value of None from your re.search() call, which might not be within the scope of this question anymore.
@DavidArenburg Nice catch. Fixed.
6

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.

answered Apr 23, 2015 at 17:46

5 Comments

Now after running AttributeError: 'NoneType' object has no attribute 'group'
That suggests that you are now getting output, but your regex is not matching anything.
I noticed a couple of things about the regex that you might want to look at. After Temperature.* you just look for \s but you might want to look for \s+. After that, you'll have to compare to your own output, because I don't have any lines that have only digits and spaces followed by a close ) and a | at the end of the line, in fact, smartctl -A for me doesn't have any |s at all, nor any parens.
You'll have to be using sudo on this python script to begin with, right? (Great answer btw. +1)
You could conceivably use sudo inside the script, but if so you would probably want to set it up so the user running it does not require a password to execute the smartctl command.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.