子流程check_output缩短了我的输出

时间:2019-03-08 21:09:23

标签: python subprocess

我必须使用以下命令编写几个C程序在多个文件上运行所花费的时间:

time ./program filename

到电子表格,并且正在使用subprocess.check_output来获取stdout作为字符串。我应该得到一些类似的东西:

real    0m0.001s
user    0m0.001s
sys     0m0.000s

但是我得到了

b'0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 
1388maxresident)k\n0inputs+0outputs (0major+60minor)pagefaults 
0swaps\n'

我看到了用户和系统时间,但是它们在小数点后两位后被截断了。有没有一种方法可以确保输出读取所有3个小数位? 这是我的代码:

import xlwt
import subprocess

files = ('100KB.txt', '1MB.txt', '10MB.txt', '100MB.txt')
programs = ('./10kBuffer', './step2', './step3', './step4')

command = ['time', programs[0], files[0]]
out = subprocess.check_output(command, stderr=subprocess.STDOUT)
print(out)

2 个答案:

答案 0 :(得分:2)

这是因为GNU time使用默认的格式字符串(更详细),但是您需要-p选项。

引用manual

  

默认格式字符串为:

     

%Uuser%Ssystem%已使用%PCPU(%Xtext +%Ddata%Mmax)k   %Iinputs +%Ooutputs(%Fmajor +%Rminor)页面错误%Wswaps

     

指定-p选项时,将使用(便携式)输出格式:

real %e
user %U
sys %S

您还需要解码输出,否则将得到bytes而不是str,并且不会解释换行符。例如:

>>> print(b'hello\nworld\n')
b'hello\nworld\n'
>>> print('hello\nworld\n')
hello
world

所以我将按原样修复您的代码:

command = ['time', '-p', programs[0], files[0]]
out = subprocess.check_output(command, stderr=subprocess.STDOUT)
print(out.decode())

编辑:the other answer似乎可以通过使用内置的shell来帮助修复丢失的小数。您可以将两个答案混合使用以获得所需的字符串形式的输出,并带有足够的小数位数。

请注意,除非您想为命令使用事件探查器,否则似乎并不能做得更好(请参见How do I get time of a Python program's execution?

答案 1 :(得分:2)

在您的python脚本使用GNU time与在命令行上使用的内置time shell之间,您似乎感到困惑。

这来自GNU time的手册页:

  

注意:某些shell(例如bash(1))具有内置的time命令,该命令提供的功能少于此处描述的命令。要访问          真正的命令,您可能需要指定其路径名(类似于/ usr / bin / time)。

基于您期望的输出,您似乎想要内置的bash,该bash保留了3个小数位:

$ bash -c time time

real    0m0.000s
user    0m0.000s
sys     0m0.000s

$ sh -c time time
user    0m0.00s
sys     0m0.00s

$ ksh -c time time
user    0m0.00s
sys     0m0.00s

$ tcsh -c time time
0.016u 0.011s 0:00.02 100.0%    0+0k 0+0io 0pf+0w

因此,为了指定内置的bash而不是GNU time,可以将命令更改为:

command = ['bash', '-c', 'time', programs[0], files[0]]

,您应该获得期望的输出。