Вывод трубопровода подпроцесса. Открытие файлов
Мне нужно запустить несколько длительных процессов с помощью subprocess.Popen
и хотел бы иметь stdout
и stderr
от каждого автоматически подключенного к отдельным файлам журнала. Каждый процесс будет запускаться одновременно в течение нескольких минут, и я хочу, чтобы два файла журнала (stdout
и stderr
) за процесс записывались как выполняемые процессы.
Мне нужно постоянно вызывать p.communicate()
для каждого процесса в цикле, чтобы обновлять каждый файл журнала, или есть способ вызвать исходную команду Popen
, чтобы автоматически stdout
и stderr
потоковое открытие дескрипторов файлов?
Ответы
Ответ 1
Per документы,
stdin, stdout и stderr укажите исполняемые программы, стандартный ввод, стандартный вывод и стандартная ошибка файловые дескрипторы, соответственно. действительный значениями являются PIPE, существующий файл дескриптор (положительное целое число), существующий файловый объект и None.
Итак, просто передайте открытые для файлов файлов объекты как именованные аргументы stdout=
и stderr=
, и вы должны быть в порядке!
Ответ 2
Вы можете передать stdout
и stderr
в качестве параметров Popen()
subprocess.Popen(self, args, bufsize=0, executable=None, stdin=None, stdout=None,
stderr=None, preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False, startupinfo=None,
creationflags=0)
Например
>>> import subprocess
>>> with open("stdout.txt","wb") as out, open("stderr.txt","wb") as err:
... subprocess.Popen("ls",stdout=out,stderr=err)
...
<subprocess.Popen object at 0xa3519ec>
>>>
Ответ 3
Я одновременно запускаю два подпроцесса и сохраняю вывод из обоих файлов в один файл журнала. Я также построил тайм-аут для обработки подпроцессов подвешенных. Когда выход становится слишком большим, тайм-аут всегда запускается, и ни один из stdout из любого подпроцесса не сохраняется в файле журнала. Ответ, поставленный Алексом выше, не решает его.
# Currently open log file.
log = None
# If we send stdout to subprocess.PIPE, the tests with lots of output fill up the pipe and
# make the script hang. So, write the subprocess stdout directly to the log file.
def run(cmd, logfile):
#print os.getcwd()
#print ("Running test: %s" % cmd)
global log
p = subprocess.Popen(cmd, shell=True, universal_newlines = True, stderr=subprocess.STDOUT, stdout=logfile)
log = logfile
return p
# To make a subprocess capable of timing out
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
log.flush()
raise Alarm
####
## This function runs a given command with the given flags, and records the
## results in a log file.
####
def runTest(cmd_path, flags, name):
log = open(name, 'w')
print >> log, "header"
log.flush()
cmd1_ret = run(cmd_path + "command1 " + flags, log)
log.flush()
cmd2_ret = run(cmd_path + "command2", log)
#log.flush()
sys.stdout.flush()
start_timer = time.time() # time how long this took to finish
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(5) #seconds
try:
cmd1_ret.communicate()
except Alarm:
print "myScript.py: Oops, taking too long!"
kill_string = ("kill -9 %d" % cmd1_ret.pid)
os.system(kill_string)
kill_string = ("kill -9 %d" % cmd2_ret.pid)
os.system(kill_string)
#sys.exit()
end_timer = time.time()
print >> log, "closing message"
log.close()