我正在尝试编写一个时间命令行程序的简单
Python版本,除了不将真实的/usr/sys时间显示给shell,它会将它记录到数据库中.
我现在拥有的是:
wrapper.py
#!/usr/bin/python
import sys
from subprocess import Popen, PIPE
cmd = 'time ' + (' '.join(['"%s"' % v if ' ' in v else v for v in sys.argv[1:]]))
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
print p.stdout.read()
print p.stderr.read()
为简单起见,我已经排除了数据库插入代码.
但是,为了说明问题,我正在使用测试脚本:
#!/usr/bin/python
import time
for i in xrange(3):
print i
time.sleep(1)
如果我运行wrapper.py python delay.py,我想看到实时打印的秒数,然后是:
real 0m3.057s
user 0m0.030s
sys 0m0.000s
相反,我没有输出3秒钟,然后打印出来:
0
1
2
0.02user 0.00system 0:03.03elapsed 0%CPU (0avgtext+0avgdata 21632maxresident)k
0inputs+0outputs (0major+1514minor)pagefaults 0swaps
如何实时读取和打印子流程的输出?
另外,为什么时间输出与我直接在shell中运行时的输出不同,当从Python脚本中的子进程运行时变得混乱?
最佳答案 首先,为什么要使用python处理I / O?让子进程的stdout和stderr转到与python相同的位置.其次,您可以直接从python中检索资源,而不是实际使用time命令.尝试这样的事情:
#! /usr/bin/python
import os
import resource
import sys
import time
cmd = ' '.join(sys.argv[1:])
stime = time.time()
os.system(cmd) # fire off the command
etime = time.time()
# now get the resource utilization
r = resource.getrusage(resource.RUSAGE_CHILDREN)
user_time = r.ru_utime
sys_time = r.ru_stime
# resource doesn't know "clock" time, so we'll just figure that ourselves
real_time = etime - stime
print "real\t" + str(real_time)
print "user\t" + str(user_time)
print "sys\t" + str(sys_time)
这会以秒为单位打印时间.如果你真的希望它们看起来像time命令,你可以相应地格式化它们.
要回答问题的第二部分,实际上有不同的“时间”命令.当你作为python的孩子运行它时,你得到的是/usr/bin/time的输出.当您手动运行它时,您将获得shell的内置时间版本.尝试在shell提示符下键入“type -a time”.另外,尝试运行你的测试程序:“/usr/bin/time ./test.py”,你应该看到第二种形式.