¿Por qué suministrar stdin a subprocess.Popen hace que lo que se escribe en stdout cambie?

Estoy usando el subproceso.Popen de Python para realizar algo de FTP utilizando el cliente binario del sistema operativo host. No puedo usar ftplib o cualquier otra biblioteca por varias razones.

El comportamiento del binario parece cambiar si adjunto un controlador estándar a la instancia de Popen. Por ejemplo, usando el cliente ftp de XP, que acepta un archivo de texto de comandos para emitir:

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

comandos.txt:

 binary get /testfiles/100.KiB quit 

Cuando también suministras stdin, todo lo que obtienes en stdout es:

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

Inicialmente, pensé que esto era una peculiaridad del cliente de XP ftp, tal vez sabiendo que no estaba en modo interactivo y, por lo tanto, limitando su salida. Sin embargo, el mismo comportamiento ocurre con el ftp de OS X (todas las respuestas del servidor faltan en la salida estándar si se proporciona la entrada estándar), lo que me lleva a pensar que este es un comportamiento normal.

En Windows puedo usar el modificador -s para hacer un script efectivo de ftp sin usar stdin, pero en otras plataformas, uno se basa en el shell para ese tipo de interacción.

La versión de Python es 2.6.x en ambas plataformas. ¿Por qué proporcionar un identificador para stdout stdut de cambio, y dónde han ido las respuestas del servidor?

Creo que leí en alguna parte (pero no recuerdo dónde) que el cliente de Windows ftp vino de una de las implementaciones originales de BSD. En eso ciertamente compartiría alguna relación con la implementación ftp de Mac OS X.

Para mí, esto no está relacionado con Popen sino con la implementación del progtwig ftp del cliente, que realiza algunas comprobaciones sobre el contexto en el que se inicia (para ver si está interactuando con un script humano o de shell), usando isatty (3) como Mencionó con Ignacio en su respuesta. Esta es una práctica común para los progtwigs que se pueden utilizar en ambos contextos. Un ejemplo bien conocido es la implementación grep de GNU para la opción –color = auto: coloreará la salida solo si stdout es un tty, y no si la salida de grep se canaliza a otro comando.

El progtwig puede usar isatty(3) para detectar la presencia de un tty en una entrada estándar.