Python Shell Wrapper

我正在尝试编写一个时间命令行程序的简单
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”,你应该看到第二种形式.

点赞