首页 > 解决方案 > Subprocess check_output cutting my output short

问题描述

I have to write the time it takes for several C programs to run on several files using:

time ./program filename

to a spread sheet and am using subprocess.check_output to get the stdout as a string. I should get something along the lines of:

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

but I get:

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

I see the user and system time but they get cut off after two decimal places. Is there a way to make sure the output reads all 3 decimal places? Here is my code:

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)

标签: pythonsubprocess

解决方案


that's because GNU time uses the default format string, more detailed, but you need -p option.

Quoting the manual:

The default format string is:

%Uuser %Ssystem %Eelapsed %PCPU (%Xtext+%Ddata %Mmax)k %Iinputs+%Ooutputs (%Fmajor+%Rminor)pagefaults %Wswaps

When the -p option is given, the (portable) output format is used:

real %e
user %U
sys %S

You also need to decode the output or you'll get bytes instead of str, and newlines won't be interpreted. ex:

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

So I would fix your code as is:

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

EDIT: the other answer seems to help fixing the missing decimals by using shell built-in. You can mix both answers to get the output you need as string, with enough decimals.

Note that it doesn't seem you can do much better, unless you want to use a profiler for your command (see How do I get time of a Python program's execution?)


推荐阅读