2012-07-20 35 views
0

我正在寫一個python(2.7)腳本,用於檢查是否有一些文件丟失並通過wget下載它們。一切工作正常,但下載完成後,腳本應該退出,bash(我從哪裏啓動python腳本)沒有正確顯示。 我有光標,可以輸入東西,但標準提示不顯示。我必須調整終端窗口的大小以正確顯示提示。這可能是什麼原因?使用Python中的wget與Popen

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過程的調用方式有關。最後的命令打印「完成」實際上是在wget將其所有輸出寫入shell之前完成的。

+2

你應該考慮使用'urllib.urlretrieve()',而不是'wget'和'os.path中.exists()'而不是打開所有文件(並且不關閉它們)。 – 2012-07-20 13:51:16

+0

你應該真的考慮@SvenMarnach所做的評論。如果您可以使用Python庫執行相同的任務,則無需依賴系統程序(如'wget')。處理輸出更容易,並且不會因爲每個文件啓動一個新進程而導致系統開銷。 http://docs.python.org/library/urllib2.html – 2012-07-20 14:31:06

回答

0

只需添加一個.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將返回寫入stdoutNone的錯誤中的輸出,因爲它不是轉發到PIPE(你會看到它在終端上,而不是)。

Btw。你應該關閉打開的文件對象(以檢查文件是否存在,你可以在os.path使用功能例如os.path.exists

+0

不,這樣會工作,wget stderr-output將被重定向到控制檯而不是管道,而'communic'將返回None而不是串。 – dav1d 2012-07-20 14:56:10

+0

Thx!它的工作原理是這樣的:p = Popen(命令,stdout = PIPE,stderr = PIPE) stdout,stderr = p.communicate()。這是什麼原因?我是否必須將wget的stderr輸出通過.communicate存儲到stderr中?爲什麼? – Michbeckable 2012-07-20 14:58:20

+0

「溝通」只是一種等待過程結束的安全方式。您也可以使用它將一次性輸入發送到stdin:'.communicate(input_to_stdin)'。 – dav1d 2012-07-20 15:00:25

0

wget的寫入其統計stderr,這就是爲什麼它打亂你的終端。 stdout和stderr會以不同的時間間隔進行刷新和查詢,因此您的Done可能在wget的輸出之前出現。

修復方法是撥wget-q或重定向stderr使用stderr=open("/dev/null", "w")或類似的東西。

另外,您應該使用.communicate()來避免管道問題。

0

您可以使用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" 
+0

順便說一句,沒有任何特別的理由將stdout引導到管道,因爲你似乎沒有使用它。 – Marvin 2012-07-20 13:59:50