我正在使用Popen调用一个外壳脚本,它连续地将其stdout和stderr写入日志文件。有没有办法同时连续输出日志文件(到屏幕),或者让外壳脚本同时写入日志文件和stdout?
我主要想在Python中做这样的事情:
cat file 2>&1 | tee -a logfile #"cat file" will be replaced with some script
同样,这将stderr/stdout管道连接到tee,tee将其写入stdout和我的日志文件。
我知道如何用Python将stdout和stderr写入日志文件。我被困的地方是如何将这些复制回屏幕:
subprocess.Popen("cat file", shell=True, stdout=logfile, stderr=logfile)
当然,我可以这样做,但是没有tee和shell文件描述符重定向,有什么方法可以做到这一点吗
subprocess.Popen("cat file 2>&1 | tee -a logfile", shell=True)
为交互式应用程序逐字节写入终端
此方法立即写入它到达stdout的任何字节,这更密切地模拟了te
的行为,尤其是对于交互式应用程序。
main.py
#!/usr/bin/env python3
import os
import subprocess
import sys
with subprocess.Popen(sys.argv[1:], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc, \
open('logfile.txt', 'bw') as logfile:
while True:
byte = proc.stdout.read(1)
if byte:
sys.stdout.buffer.write(byte)
sys.stdout.flush()
logfile.write(byte)
# logfile.flush()
else:
break
exit_status = proc.returncode
sleep.py
#!/usr/bin/env python3
import sys
import time
for i in range(10):
print(i)
sys.stdout.flush()
time.sleep(1)
首先,我们可以进行非交互式的健全性检查:
./main.py ./sleep.py
我们看到它实时计数到标准输出。
接下来,对于交互式测试,您可以运行:
./main.py bash
然后,您键入的字符会在您键入时立即显示在终端上,这对于交互式应用程序非常重要。这是您跑步时发生的情况:
bash | tee logfile.txt
此外,如果希望输出立即显示在ouptut文件上,还可以添加:
logfile.flush()
但是tee不能做到这一点,我担心这会影响性能。您可以使用以下工具轻松测试这一点:
tail -f logfile.txt
相关问题:子进程命令的实时输出
在Ubuntu 18.04、Python 3.6.7上测试。
模拟:subprocess.call("命令2
#!/usr/bin/env python2
from subprocess import Popen, PIPE, STDOUT
p = Popen("command", stdout=PIPE, stderr=STDOUT, bufsize=1)
with p.stdout, open('logfile', 'ab') as file:
for line in iter(p.stdout.readline, b''):
print line, #NOTE: the comma prevents duplicate newlines (softspace hack)
file.write(line)
p.wait()
要修复可能的缓冲问题(如果输出延迟),请参阅Python中的链接:从subprocess.communicate()读取流输入。
这是Python 3版本:
#!/usr/bin/env python3
import sys
from subprocess import Popen, PIPE, STDOUT
with Popen("command", stdout=PIPE, stderr=STDOUT, bufsize=1) as p, \
open('logfile', 'ab') as file:
for line in p.stdout: # b'\n'-separated lines
sys.stdout.buffer.write(line) # pass bytes as is
file.write(line)
您可以使用管道从程序的标准输出读取数据,并将其写入您想要的所有位置:
import sys
import subprocess
logfile = open('logfile', 'w')
proc=subprocess.Popen(['cat', 'file'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in proc.stdout:
sys.stdout.write(line)
logfile.write(line)
proc.wait()
更新
在python 3中,universal\u newlines参数控制管道的使用方式。如果False,管道读取返回对象,可能需要解码(例如,
行。解码('utf-8')
)以获取字符串。如果为True,python将为您解码
在3.3版中更改:当universal_newlines为True时,类使用编码locale.getpreferredencoding(False)而不是locale.getpreferredencoding()。有关此更改的更多信息,请参阅io. TextIOWrapper类。
问题内容: 此代码是否同时写入日志文件和控制台? 问题答案: 不,它不会同时写入两者。只会写入控制台。关于原始代码的简短说明。我想您在某处定义,但是代码仍然不正确。您需要在语句中使用引号,例如: 因为我认为您是要附加到文件中。否则,您的代码将抛出一个因为未定义的变量。 但是,正如其他人所说,您应该强烈考虑使用日志记录模块。这是一个如何同时写入控制台和日志文件的简单示例。该代码部分源自此处和此处:
我决定使用slf4j而不是Java自己的日志记录。我已经成功地使用SLF4J登录到控制台。但我不知道如何将其写入日志文件。日志文件将帮助我们收集运行时可能出现的错误。 我通过这样做来实现slf4j, 私有静态最终org.slf4j.LOGGER LOGGER=org.slf4j.loggerfactory.getlogger(class1.class); PropertyConfigurator.
问题内容: 我遇到一种情况,我想将我创建的所有日志写入文本文件。 我们正在使用java.util.logging.Logger API生成日志。 我试过了: 但是仍然只能在控制台上获取我的日志。 问题答案: 试试这个样本。这个对我有用。 在MyLogFile.log产生输出 编辑: 要删除控制台处理程序,请使用 因为ConsoleHandler已向父记录器注册,所有记录器都源自该记录器。
问题内容: 我正在尝试使用Go写入日志文件。 我尝试了几种方法,但都失败了。这是我尝试过的: 日志文件被创建,但是没有任何打印或附加到该文件。为什么? 问题答案: 过去的工作方式一定不同,但这对我有用: 基于Go文档,不能用于,因为它会打开文件“供阅读:” 打开命名文件以供读取。如果成功,则可以使用返回文件上的方法进行读取;关联的文件描述符具有mode 。如果有错误,它将是类型。 编辑 检查后移至
我在写构建脚本。我想记录正在进行的一切,但我也想在它运行的时候看到一切。做这件事的最佳做法是什么?
问题内容: 如何使用Python中的日志记录模块写入文件?每当我尝试使用它时,它只会打印出消息。 问题答案: 一个使用而不是一个例子 按顺序,这五个部分执行以下操作: 设置输出文件() 将其设置为追加而不是覆盖() 确定输出消息的格式() 确定输出时间的格式() 并确定它将接受的最低消息级别()。