2013-06-27 2 views
2

Я пытаюсь собрать stderr в памяти вместо того, чтобы напрямую записывать его в файл или стандартный вывод. Я делаю это, поэтому я могу сгенерировать файл журнала ошибок определенным образом. Я нашел библиотеку под названием StringIO, которая является «файлом» в памяти. Я не думаю, что это трюк. Вот мой код:Сбор stderr в памяти с subprocess.call

 buffer = StringIO.StringIO() 
     status = subprocess.call(args, stdout=log_fps["trace"], stderr=buffer) 

     if status and self.V_LEVEL: 
      sys.stderr.write(buffer.getvalue()) 
      print "generated error" 

     if status: 
      log_fps["fail"].write("==> Error with files %s and %s\n" % (domain_file, problem_file)) 
      log_fps["fail"].write(buffer.getvalue()) 

Я получаю следующее сообщение об ошибке:

Traceback (most recent call last): 
    File "./runit.py", line 284, in <module> 
    launcher.run_all_cff_domain_examples("ring") 
    File "./runit.py", line 259, in run_all_cff_domain_examples 
    result = self.run_clg(in_d["domain"], in_d["problem"], in_d["prefix"]) 
    File "./runit.py", line 123, in run_clg 
    status = subprocess.call(args, stdout=log_fps["trace"], stderr=buffer) 
    File "/usr/lib/python2.7/subprocess.py", line 493, in call 
    return Popen(*popenargs, **kwargs).wait() 
    File "/usr/lib/python2.7/subprocess.py", line 672, in __init__ 
    errread, errwrite) = self._get_handles(stdin, stdout, stderr) 
    File "/usr/lib/python2.7/subprocess.py", line 1075, in _get_handles 
    errwrite = stderr.fileno() 
AttributeError: StringIO instance has no attribute 'fileno' 

Я думаю, это означает, что я не могу использовать StringIO для сбора STDERR в памяти. Что еще я могу сделать, за исключением записи в файл в/tmp?

ответ

2
stdout = subprocess.check_output(args) 

См. Документацию check_output для получения дополнительных сведений.

Если вы не хотите, чтобы захватить stdout, используйте Popen.communicate:

from subprocess import Popen, PIPE 

p = Popen(args, stdout=log_fps["trace"], stderr=PIPE) 
_, stderr = p.communicate() 
+0

Это не совсем то, что я хочу, так как check_output поднимает CalledProcessError на ненулевым кодом завершения, и я ожидаю, команда часто не , – BlackSheep

+0

Кроме того, вызов popen существенно отличается от моего вызова, потому что теперь программа оболочки работает асинхронно. Если вы поместите Popen.wait(), то не сможете читать из общения. Если вы поместите p.wait() после связи, вы не сможете записать весь вывод в stderr. Я уже пробовал этот подход. – BlackSheep

+0

Наконец, ваша первая команда 'stdout, stderr = subprocess.check_output (args)' не работает для меня. Я получаю 'ValueError: слишком много значений для распаковки'. – BlackSheep

0
import subprocess 

p = subprocess.Popen(args, stdout=log_fps["trace"], stderr=subprocess.PIPE) 

_, stderr = p.communicate() 
print stderr,