Python “的打印输出”;时间“;不丢失格式的shell命令
出于某种原因,当我从终端运行“time./”时,我得到以下格式: real 0m0.090s user 0m0.086s sys 0m0.004sPython “的打印输出”;时间“;不丢失格式的shell命令,python,bash,time,Python,Bash,Time,出于某种原因,当我从终端运行“time./”时,我得到以下格式: real 0m0.090s user 0m0.086s sys 0m0.004s 是否有任何方法可以强制使用第一个(real,user,sys)格式?来自工时文档: 实用程序完成后,time将经过的总时间、系统开销消耗的时间以及用于执行实用程序的时间写入标准错误流。 我的。您捕获的是stdout流,而不是stderr流,因此您看到的任何输出都一定是其他东西破坏Python stderr流的结果 捕获s
是否有任何方法可以强制使用第一个(real,user,sys)格式?来自
工时
文档:
实用程序完成后,time将经过的总时间、系统开销消耗的时间以及用于执行实用程序的时间写入标准错误流。
我的。您捕获的是stdout流,而不是stderr
流,因此您看到的任何输出都一定是其他东西破坏Python stderr流的结果
捕获stderr
:
0.09user 0.00system 0:00.09elapsed
proc = subprocess.Popen("time ./<binary>", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
第一:关于需要捕获time
的stderr
而不是stdout
是正确的
另外,至少在较旧版本的Python(如3.1)上,a包含一些可以被视为“输出”的内容。试图打印一个
只会导致:
如果以后的版本可以打印,则必须对其内容进行一些处理,可能包括损坏输出
从Popen
对象读取(和打印)
Popen
对象有一个可读取的类文件对象。您可以像读取任何其他类似文件的对象一样从中读取,但不建议这样做。引用粉红色的大字:
警告
使用而不是,或避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致死锁
要打印您的Popen
的内容,您必须:
使用子进程,将其返回的2元组(stdout
,stderr
)分配给局部变量
将变量的内容转换为字符串---默认情况下,它是一个字节
对象,就好像“文件”是以二进制模式打开的一样
下面是一个小程序,它可以打印shell命令的stderr
输出,而不会弄脏(不包括从ASCII到Unicode的转换)
#/usr/bin/env蟒蛇3
导入子流程
def main():
结果=子流程.Popen(
“时间睡眠0.2”,
shell=True,
stderr=子流程.PIPE,
)
stderr=result.communicate()[1]
stderr_text=stderr.decode('us-ascii').rstrip('\n')
#打印(标准文本)#一次打印所有行。
#或者,如果您想逐行处理输出。。。
lines=stderr\u text.split('\n')
对于行中的行:
打印(行)
返回
如果“\uuuu main\uuuuuu”==\uuuuuuuu name\uuuuuuu:
main()
此输出在旧的Fedora Linux系统上,运行bash
,将LC\u ALL
设置为“C”
:
实际0.201s
用户0.000s
系统0m0.001s
请注意,您需要在我的脚本的stderr\u text=stderr.decode(…)
行周围添加一些错误处理。。。据我所知,time
根据本地化、环境变量等发出非ASCII字符
备选方案:universal\u新行
您可以使用保存一些解码样板文件。它自动将字节
转换为字符串
:
如果universal_newlines为True
,则这些文件对象将使用返回的编码以文本流的方式打开。[……]
def main_universal_newlines():
结果=子流程.Popen(
“时间睡眠0.2”,
shell=True,
stderr=子流程.PIPE,
universal_newlines=True,
)
stderr\u text=result.communicate()[1].rstrip('\n')
lines=stderr\u text.split('\n')
对于行中的行:
打印(行)
返回
请注意,我仍然必须手动剥离最后一个'\n'
,以便与shell的输出完全匹配。还要求以POSIX模式传递-p
,以获得精确/可移植的输出。@PeterWood:-p
不带制表符和浮点格式的输出。@Xpl0:等等,现在您可以通过捕获的stderr
来获得它了吗?我不能复制这个;我得到了换行和非POSIX输出。什么操作系统?print(repr(stderr))
的输出是什么?我在OSX和DebianLinux上进行了测试。同样的事情也发生在简单的命令“timels”上。当通过终端执行时,我得到了换行符和非POSIX输出,但我得到了“0.00user 0.00system 0:00.00Appeased”,做了我们正在讨论的事情。@Xpl0:strange;因为即使是time-p
输出也包含换行符,这就是我在这里要求repr(stderr)
输出的原因。尝试运行/bin/sh
,(打开一个新shell),然后运行时间ls
。退出该shell会使您回到常规shell。如果显示相同的变化,您能告诉我常规和子shell中的哪个时间
产生了什么吗?您如何显示/打印
结果
?或者这正是您的控制台或某个IDE的“输出”窗口中显示的内容?@KevinJ.Chase只是一个简单的打印。您使用的是什么版本的Python?在我的Python3.1(我手头的所有工具)上,Popen
没有自定义的\uuu str\uu
方法,所以print(result)
只显示
@KevinJ.Chase我使用的是Python2.7.6。顺便说一句,我不是在打印“result”,而是在打印“stderr”(将Martjin的代码视为更新版本)。有什么想法吗?@Xpl0:我已经用一种使用(更安全的)通信
方法的替代方法替换了我原来的答案。此外,我还建议使用universal\u新行
,以避免将字节
显式转换为str
。
proc = subprocess.Popen("time ./<binary>", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
proc = subprocess.Popen("time ./<binary>", shell=True, executable='/bin/bash',
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()