Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将python中的wget与Popen一起使用_Python_Shell_Popen - Fatal编程技术网

将python中的wget与Popen一起使用

将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

我正在编写一个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之前完成的。

只需在输出之后添加一个命令,如下所示:

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
,如果您直接从它们读取,这可能会导致问题(如死锁)。