import serial
import string
from time import sleep
from subprocess import call, check_call, CalledProcessError
import logging
import random
import signal
import os
LOG_FILENAME = "/tmp/dfu.log"
LOG_FD = open(LOG_FILENAME, "w")
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
dfu_image_list = ['/tmp/sample.dfu']
while True:
try:
for test_file in dfu_image_list:
logging.info("\n==================\nbegin dfu download test")
check_call('sudo dfu-util -vD /tmp/sample.dfu', shell=True,
stdout=LOG_FD, stderr=LOG_FD)
logging.info("Download completed successfully!")
sleep(5)
except CalledProcessError as e:
msg = "dfu-util failed with return code :%s \n\nMessage:%s" %
(e.returncode, e.message)
logging.warning(msg)
logging.warning("USB device likely needs time to re-enumerate,
waiting 10 seconds before restarting")
sleep(10)
except OSError:
logging.error("dfu-util executable not found!")
exit(1)
执行上面的python脚本会在/tmp/dfu.log中提供日志。 但是,日志文件中的日志来自函数check_call。 预期的行为是主线程日志,如
logging.info("\n==================\nbegin dfu download test")
logs of function check_call
logging.info("Download completed successfully!").
然而,只有函数check_call的日志被反映,主线程记录如
begin dfu download test
Download completed successfully!
没有反映到日志文件中。
答案 0 :(得分:0)
请记住,日志记录模块会执行一些缓冲,这意味着使用log.something()
编写日志并不一定意味着此日志将写入文件。
此外,您正在打开文件两次,并从不同的位置写入文件。通常这是一个坏主意,即使Linux是先发制人的,你刷新日志并且可能工作仍然是个坏主意。
您communicate()
使用该流程而不是check_call()
,然后根据需要记录stdout
或stderr
。例如:
for image in dfu_image_list:
logging.info('=' * 10)
logging.info('Begin dfu download using {}'.format(image))
process = Popen(['sudo', 'dfu-util', '-vD', image], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
logging.info(stdout)
if stderr:
logging.warning(stderr)
logging.info('Download completed successfully!')
顺便说一句,你的循环逻辑是有缺陷的。因为任何错误都会重新启动dfu_image_list图像的循环。
我认为这更像是你想做的事情:
from sys import exit
from time import sleep
from subprocess import Popen, PIPE, CalledProcessError
import logging
LOG_FILENAME = "/tmp/dfu.log"
ATTEMPTS = 3
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
def download(where):
logging.info('=' * 10)
logging.info('Begin dfu download to {}'.format(where))
for attempt in range(ATTEMPTS):
logging.info('Attempt #{}...'.format(attempt + 1))
try:
process = Popen(
['sudo', 'dfu-util', '-vD', where],
stdout=PIPE, stderr=PIPE
)
stdout, stderr = process.communicate()
logging.info(stdout)
if stderr:
logging.warning(stderr)
logging.info('Download completed successfully!')
return True
except CalledProcessError as e:
logging.warning(
'dfu-util failed with return code {}'.format(e.returncode)
)
logging.warning(
'Message:\n{}'.format(e.message)
)
logging.warning(
'USB device likely needs time to re-enumerate, '
'waiting 10 seconds before restarting...'
)
sleep(10)
continue
except OSError:
logging.critical('dfu-util executable not found!')
return False
if __name__ == '__main__':
if not download('/tmp/sample.dfu'):
exit(1)