2016-01-19 3 views
1
>>> import subprocess 
>>> subprocess.check_output("smartctl -d ata -a /dev/sda", shell=True) 
"output of above command prints normally" 
>>> subprocess.check_output("smartctl -d ata -a /dev/sdb", shell=True) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/subprocess.py", line 544, in check_output 
     raise CalledProcessError(retcode, cmd, output=output) 
subprocess.CalledProcessError: Command 'smartctl -d ata -a /dev/sdb' returned non-zero exit status 64 

Может кто-нибудь объяснить мне, почему приведенная выше команда с sda работает нормально, но возвращает ошибку с помощью sdb? sdc также работает для записи. Кроме того, я знаю об опасности использования shell = True. Я изучаю python и сталкивался с этой проблемой при написании тестового скрипта.python subprocess.check_output возвращает CalledProcessError для некоторых команд

ответ

1

Чтобы узнать выходы и ошибки используют

import subprocess 
c=subprocess.Popen("smartctl -d ata -a /dev/sdb",stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True) 
output,error=c.communicate() 
#now check your error or output 
1

Вы можете легко увидеть, что с SDB:

try: 
    subprocess.check_output("smartctl -d ata -a /dev/sdb", shell=True) 
except subprocess.CalledProcessError, e: 
    print e.output 
+0

Интересно, что код имеет следующую ошибку: NameError: name 'CalledProcessError' не определен. отредактируйте его на subprocess.CalledProcessError. – user2503227

+0

Спасибо, я отредактировал свой ответ. В качестве альтернативы вы можете написать 'from subprocess import CalledProcessError' перед моей частью кода. –

+0

Когда я перехожу к subprocess.CalledProcessError и печатаю e.output, я получаю вывод команды smartctl с кажущимися ошибками. Странно, это как-то ожидалось? – user2503227

1

Команда smartctl возвращает значение 64. Согласно manual page возвращаемое значение равно бит. Преобразование 64 в двоичный выход 01000000, поэтому бит 6 установлен (самый правый бит бит 0). Согласно вышеупомянутой странице руководства:

Bit 6: The device error log contains records of errors.

Если вы можете использовать Python 3.5, вы можете использовать новый высокоуровневый API subprocess.run(). Это позволяет как захватить возвращаемое значение, так и стандартный вывод/ошибку.

prog = ['smartctl', '-d', 'ata', '-a', '/dev/sda'] 
result = subprocess.run(prog, stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 
if result.returncode == 0: 
    print(result.stdout) 
else: 
    print('smartctl returned error', result.returncode) 
+0

Закончился с подпроцессом. Вариант покупки, так как это лучше соответствует моим потребностям. Желательно искать варианты, совместимые с 2.7 и 3.5, но он должен работать с 2.7. Спасибо за информацию, хотя – user2503227

Смежные вопросы