我使用Python的subprocess.Popen使用主機操作系統的二進制客戶端來執行一些FTP。出於各種原因,我無法使用ftplib或任何其他庫。爲什麼提供stdin給subprocess.Popen會導致寫入stdout的內容發生變化?
如果我將一個stdin處理程序附加到Popen實例,二進制的行爲似乎會改變。例如,使用XP的FTP客戶端,它接受命令的文本文件的問題:
>>>from subprocess import Popen, PIPE
>>>p = Popen(['ftp','-A','-s:commands.txt','example.com'], stdout=PIPE)
>>>p.communicate()[0]
'Connected to example.com.
220 ProFTPD 1.3.1 Server (Debian) ...
331 Anonymous login ok, send your complete email address as your password
<snip>
ftp> binary
200 Type set to I
ftp> get /testfiles/100.KiB
200 PORT command successful
150 Opening BINARY mode data connection for /testfiles/100.KiB (102400 bytes)
226 Transfer complete
ftp: 102400 bytes received in 0.28Seconds 365.71Kbytes/sec.
ftp> quit
>>>
commands.txt中:
binary
get /testfiles/100.KiB
quit
當還提供標準輸入,你在標準輸出得到的是:
>>>from subprocess import Popen, PIPE
>>>p = Popen(['ftp','-A','-s:commands.txt','example.com'], stdin=PIPE, stdout=PIPE)
>>>p.communicate()[0]
'binary
get /testfiles/100.KiB
quit'
>>>
最初我以爲這是XP ftp客戶端的一個怪癖,也許知道它不是交互模式,因此限制了它的輸出。但是,OS X的ftp也會發生同樣的行爲 - 如果提供stdin,所有服務器響應都將從stdout中丟失 - 這讓我認爲這是正常行爲。
在Windows中,我可以使用-s開關在不使用stdin的情況下有效地腳本ftp,但在其他平臺上依賴shell來進行這種交互。
兩種平臺上的Python版本是2.6.x。爲什麼要爲stdin提供stdout的句柄,以及服務器響應的位置在哪裏?
你有沒有考慮過使用'ftplib'? http://docs.python.org/library/ftplib.html – 2010-03-01 14:31:24
你無法使用ftplib的原因是什麼?它帶有你的Python發行版嗎? – ghostdog74 2010-03-01 14:33:53