将python中的wget与Popen一起使用



我正在编写一个python(2.7)脚本,该脚本检查是否缺少一些文件,并通过wget下载这些文件。一切都很好,但在下载完成并且脚本应该退出后,bash(我启动python脚本的地方)没有正确显示。我有光标,可以输入内容,但没有显示标准提示。我必须调整终端窗口的大小以使提示正确显示。这可能是什么原因?

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之前完成的。

只需在输出后添加一个.communicate(),如下所示:

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将返回写入stderr的stdoutNone的输出,因为它没有转发到PIPE(您将在终端上看到它)。

Btw。应该关闭打开的文件对象(要检查文件是否存在,可以使用os.path中的函数,例如os.path.exists)

wget将其统计数据写入stderr,这就是它扰乱终端的原因。stdout和stderr以不同的时间间隔刷新和查询,因此Done可能显示在wget的输出之前。

修复方法是使用-q调用wget,或者也使用stderr=open("/dev/null", "w")或类似的方法重定向stderr

此外,您可能应该使用.communicate()来避免管道问题。

您可以使用os.system(但请参阅http://docs.python.org/release/2.5.2/lib/node536.html)。基本上,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,它也可以工作(完全模式)

最新更新