Почему делает предоставление stdin для подобрабатывания. Popen вызывают то, что записано в stdout для изменения?

Я использую подпроцесс Python. Popen для выполнения некоторого FTP с помощью двоичного клиента хостовой операционной системы. Я не могу использовать ftplib или любую другую библиотеку по различным причинам.

Поведение двоичного файла, кажется, изменяется, если я присоединяю stdin обработчик к экземпляру Popen. Например, с помощью клиента ftp XP, который принимает, что текстовый файл команд выходит:

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

Также предоставляя 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'  
>>>

Первоначально я думал, что это было причудой клиента ftp XP, возможно, зная, что это не было в интерактивном режиме и поэтому ограничении его вывода. Однако то же поведение происходит с ftp OS X - все ответы сервера отсутствуют в stdout, если stdin предоставляется - который приводит меня думать, что это - нормальное поведение.

В Windows I может использовать переключатель-s для эффективных сценариев ftp, не используя stdin, но на других платформах каждый полагается на оболочку для такого взаимодействия.

Версия Python 2.6.x на обеих платформах. Почему был бы, предоставляя дескриптор для stdout изменения stdin, и куда ответы сервера перешли в?

6
задан Matt 28 August 2017 в 08:07
поделиться

2 ответа

Кажется, я где-то читал (но не могу вспомнить где), что ftp-клиент Windows пришел из одной из исходных реализаций BSD. В этом он определенно будет иметь некоторые отношения с реализацией ftp в Mac OS X.

Для меня это связано не с Popen, а с реализацией клиентской программы ftp, которая выполняет некоторые проверки контекста, в котором она запускается (чтобы увидеть, взаимодействует ли она с человеком или сценарием оболочки), используя isatty ( 3) как упоминалось с Игнасио в его ответе. Это обычная практика для программ, которые можно использовать в обоих контекстах. Хорошо известным примером является реализация GNU grep для параметра --color = auto: он раскрашивает вывод, только если stdout является tty, а не если вывод grep передается другой команде.

4
ответ дан 9 December 2019 в 22:32
поделиться

Программа может использовать isatty (3) для обнаружения присутствия tty на стандартном вводе.

7
ответ дан 9 December 2019 в 22:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: