我有一个Linux的Python程序几乎看起来像这样:
import os
import time
process = os.popen("top").readlines()
time.sleep(1)
os.popen("killall top")
print process
Run Code Online (Sandbox Code Playgroud)
该程序挂起在这一行:
process = os.popen("top").readlines()
Run Code Online (Sandbox Code Playgroud)
这种情况发生在保持更新输出的工具中,如"Top"
我最好的考验:
import os
import time
import subprocess
process = subprocess.Popen('top')
time.sleep(2)
os.popen("killall top")
print process
Run Code Online (Sandbox Code Playgroud)
它比第一个(它被砍掉)效果更好,但它返回:
<subprocess.Popen object at 0x97a50cc>
Run Code Online (Sandbox Code Playgroud)
第二次试验:
import os
import time
import subprocess
process = subprocess.Popen('top').readlines()
time.sleep(2)
os.popen("killall top")
print process
Run Code Online (Sandbox Code Playgroud)
和第一个一样.它由于"readlines()"而被绞死
它的返回应该是这样的:
top - 05:31:15 up 12:12, 5 users, load average: 0.25, 0.14, 0.11
Tasks: 174 total, 2 running, 172 sleeping, 0 stopped, 0 zombie
Cpu(s): 9.3%us, …Run Code Online (Sandbox Code Playgroud) 尝试将子进程的输出重定向到文件.
server.py:
while 1:
print "Count " + str(count)
sys.stdout.flush()
count = count + 1
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)
Laucher:
cmd = './server.py >temp.txt'
args = shlex.split(cmd)
server = subprocess.Popen( args )
Run Code Online (Sandbox Code Playgroud)
输出显示在屏幕上,temp.txt保持为空.我究竟做错了什么?
作为背景我试图捕获已经编写的程序的输出.
我不能用:
server = subprocess.Popen(
[exe_name],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
因为该程序可能不会刷新.相反,我打算通过fifo重定向输出.如果我手动启动server.py,这很好,但显然不是因为我Popen()导致重定向不起作用.
ps -aux显示server.py正确启动.
我通过子进程调用rtmpdump并尝试将其输出重定向到文件.问题是我根本无法重定向它.
我尝试首先将sys.stdout设置为打开的文件.这适用于ls,但不适用于rtmpdump.我也试过设置sys.stderr只是为了确保它也没有用.
我尝试使用命令行参数的">>文件",但它似乎不起作用.
同样为了记录,由于某种原因,Eclipse打印rtmpdump的输出,即使我使用subprocess.call而不是subprocess.check_output,也无需调用print方法.这是黑魔法!
有什么建议?
编辑:这是一些示例代码.
# /!\ note: need to use os.chdir first to get to the folder with rtmpdump!
command = './rtmpdump -r rtmp://oxy.videolectures.net/video/ -y 2007/pascal/bootcamp07_vilanova/keller_mikaela/bootcamp07_keller_bss_01 -a video -s http://media.videolectures.net/jw-player/player.swf -w ffa4f0c469cfbe1f449ec42462e8c3ba16600f5a4b311980bb626893ca81f388 -x 53910 -o test.flv'
split_command = shlex.split(command)
subprocess.call(split_command)
Run Code Online (Sandbox Code Playgroud) 我目前正在复制以下Unix命令:
cat command.info fort.13 > command.fort.13
Run Code Online (Sandbox Code Playgroud)
在Python中使用以下内容:
with open('command.fort.13', 'w') as outFile:
with open('fort.13', 'r') as fort13, open('command.info', 'r') as com:
for line in com.read().split('\n'):
if line.strip() != '':
print >>outFile, line
for line in fort13.read().split('\n'):
if line.strip() != '':
print >>outFile, line
Run Code Online (Sandbox Code Playgroud)
这是有效的,但必须有一个更好的方法.有什么建议?
编辑(2016):
四年后,这个问题又开始受到关注.我在这里用更长的Jupyter笔记本写了一些想法.
问题的关键在于我的问题与(我意想不到的)行为有关readlines.我可以更好地回答我的目标,这个问题可以更好地回答read().splitlines().
如果需要定期检查stdout正在运行的进程.例如,进程是tail -f /tmp/file在python脚本中生成的.然后每隔x秒,该子进程的stdout被写入字符串并进一步处理.脚本最终会停止子进程.
解析子check_output进程的stdout,如果直到现在使用,这似乎不起作用,因为进程仍在运行并且不会产生确定的输出.
>>> from subprocess import check_output
>>> out = check_output(["tail", "-f", "/tmp/file"])
#(waiting for tail to finish)
Run Code Online (Sandbox Code Playgroud)
应该可以为子进程使用线程,以便可以处理多个子进程的输出(例如tail -f/tmp/file1,tail -f/tmp/file2).
如何启动子进程,定期检查和处理其标准输出并最终以多线程友好的方式停止子进程?python脚本在Linux系统上运行.
目标不是连续读取文件,tail命令是一个示例,因为它的行为与使用的实际命令完全相同.
编辑:我没想到这个,文件不存在.check_output现在只需等待该过程完成.
edit2:一种替代方法,使用Popen并且PIPE似乎导致相同的问题.它等待tail完成.
>>> from subprocess import Popen, PIPE, STDOUT
>>> cmd = 'tail -f /tmp/file'
>>> p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
>>> output = p.stdout.read()
#(waiting for tail to finish)
Run Code Online (Sandbox Code Playgroud) 在我的python脚本中,我试图运行一个打印输出的Windows程序.但我想将该输出重定向到文本文件.我试过了
command = 'program' + arg1 + ' > temp.txt'
subprocess.call(command)
Run Code Online (Sandbox Code Playgroud)
程序是我的程序名称,arg1是参数.但它不会将输出重定向到文本文件它只是在屏幕上打印.
任何人都可以帮我怎么做?谢谢!