将python中的wget与Popen一起使用
我正在编写一个python(2.7)脚本,用于检查是否缺少一些文件,并通过wget下载它们。一切正常,但是在下载完成并且脚本应该退出之后,bash(我开始编写python脚本的地方)没有正确显示。 我有光标,可以输入东西,但是标准提示没有出现。我必须调整终端窗口的大小以正确显示提示。这可能是什么原因将python中的wget与Popen一起使用,python,shell,popen,Python,Shell,Popen,我正在编写一个python(2.7)脚本,用于检查是否缺少一些文件,并通过wget下载它们。一切正常,但是在下载完成并且脚本应该退出之后,bash(我开始编写python脚本的地方)没有正确显示。 我有光标,可以输入东西,但是标准提示没有出现。我必须调整终端窗口的大小以正确显示提示。这可能是什么原因 tilenames = ['File1', 'File2', ...] web_url = http://... for t in tilenames: try: open
tilenames = ['File1', 'File2', ...]
web_url = http://...
for t in tilenames:
try:
open(t, 'r')
except IOError:
print 'file %s not found.' % (t)
command = ['wget', '-P', './SRTM/', web_url + t ]
output = Popen(command, stdout=subprocess.PIPE)
print "Done"
我认为这与wget进程的调用方式有关。最后一个命令print“Done”实际上是在wget将其所有输出写入shell之前完成的。只需在输出之后添加一个命令,如下所示:
tilenames = ['File1', 'File2', ...]
web_url = http://...
for t in tilenames:
try:
open(t, 'r')
except IOError:
print 'file %s not found.' % (t)
command = ['wget', '-P', './SRTM/', web_url + t ]
p = Popen(command, stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
print "Done"
communicate
将返回写入stdout和stderr的None
的输出,因为它不会转发到管道
(您将在终端上看到它)
顺便说一句,您应该关闭打开的文件对象(要检查文件是否存在,您可以使用中的功能,例如)wget将其统计信息写入
stderr
,这就是为什么它会扰乱您的终端。stdout和stderr以不同的时间间隔刷新和查询,因此您的Done
可能在wget
的输出之前显示
修复方法是使用-q
调用wget
,或者使用stderr=open(“/dev/null”,“w”)
或类似的方法重定向stderr
此外,您可能应该使用来避免管道问题。您可以使用os.system(但请参阅)。基本上,Popen旨在允许python进程读取命令输出。您似乎不需要这样做,因此下面的片段应该可以满足您的需求:
import os
import subprocess
p = subprocess.Popen(['wget','http://www.aol.com'],stdout=subprocess.PIPE)
os.waitpid(p.pid,0)
print "done"
如果添加-Q选项,WGET也工作(相当模式)
,你应该考虑使用<代码> URLLIB。URLRebug()/<代码>而不是<代码> WGET < /COD>和<代码> OS.Posith.SimultSo()/<代码>,而不是打开所有文件(而不是关闭它们)。你应该真正考虑@ @ SvenMarnach所做的评论。如果可以使用Python库执行相同的任务,则无需依赖系统程序(如wget
)。它更容易处理输出,并且不会因为为每个文件启动一个新进程而产生系统开销。顺便说一句,没有任何特别的理由将stdout定向到管道,因为您似乎没有使用它。不,这将按原样工作,wget stderr输出将重定向到控制台而不是管道,communicate
返回None而不是字符串。Thx!它的工作原理如下:p=Popen(命令,stdout=PIPE,stderr=PIPE)stdout,stderr=p.communicate()。原因是什么?我是否必须获取wget的stderr输出并通过.communicate将其存储到stderr中?为什么?沟通
只是等待过程结束的一种安全方式。您还可以使用它向stdin发送一次进程输入:。communicate(input_to_stdin)
。是的,但是p.wait()
不会给您管道的输出stdin/stderr
,如果您直接从它们读取,这可能会导致问题(如死锁)。