8

ホスト オペレーティング システムのバイナリ クライアントを使用して FTP を実行するために、Python の subprocess.Popen を使用しています。さまざまな理由で、ftplib やその他のライブラリを使用できません。

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  
>>>

コマンド.txt:

binary  
get /testfiles/100.KiB  
quit  

stdin も提供する場合、stdout で得られるのは次のとおりです。

>>>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 を効果的にスクリプト化できますが、他のプラットフォームでは、その種の対話をシェルに依存しています。

Python のバージョンは、両方のプラットフォームで 2.6.x です。stdin のハンドルを指定すると stdout が変更されるのはなぜですか? また、サーバーの応答はどこに送信されますか?

4

2 に答える 2

7

プログラムがisatty(3)標準入力の tty の存在を検出するために使用している可能性があります。

于 2010-03-01T14:29:11.767 に答える
4

Windows ftp クライアントが元の BSD 実装の 1 つに由来するということをどこか (どこか思い出せません) で読んだ気がします。その点で、Mac OS X の ftp 実装と何らかの関係を共有することは確かです。

私にとって、これは Popen とは関係ありませんが、 isatty(3) を使用して、起動されたコンテキストについていくつかのチェックを行うクライアント ftp プログラムの実装に関連しています (人間またはシェルスクリプトと対話しているかどうかを確認するため)。彼の答えでイグナシオに言及しました。これは、両方のコンテキストで使用できるプログラムの一般的な方法です。よく知られている例は、 --color=auto オプションの GNU grep 実装です。これは、標準出力が tty の場合にのみ出力を色付けし、grep の出力が別のコマンドにパイプされている場合は色付けしません。

于 2010-03-01T17:19:45.167 に答える