Я пытаюсь получить вывод команды smbclient
, которая, по сути, открывает интерактивный сеанс, в котором вы можете вводить команды.Я хочу оставить этот сеанс открытым и передать в него команды и захватить вывод.
import subprocess
command = "smbclient <someIP> -U <username>"
p = subprocess.Popen(command,shell=True, executable='/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(b"ls\n")
p.stdin.flush()
p.stdout.readline() # this blocks
p.stdin.close()
p.stdout.readline() # this works (grabs data as expected), also p.communicate() works as well but that makes sense since it closes stdin
Я не могу понять, почему нет выхода после очистки stdin
.У меня было несколько подозрений, которые я тоже проверил:
- Я пытался проверить, будет ли работать неблокирующее чтение.Я запустил
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
и сделал read()
, readline()
и т. Д. После сброса, и это не сработало. - Попытался сбросить
p.stdout
до чтения, и это не сработало. - Попытка удалить трубу
stdout
из конструктора, чтобы она просто переходила к stdout
системы.Вот где это становится действительно интересным.Если я делаю это, как только я сбрасываю stdin
, я вижу вывод в моем терминале.Я могу продолжать писать и сбрасывать, не воссоздавая процесс, и каждый раз, когда я это делаю, вывод идет на терминал, как и ожидалось, без необходимости закрывать stdin
.Так что, почему это не идет к трубе, сбивает с толку. - Пробный конвейер
tail -f mycommands.txt | smbclient <myParameters>
в подсказке bash
, и это работало просто отлично - я проверял, ждал ли он EOF или чего-то такого, чтобына самом деле обрабатывать команды. - Изменено
/bin/bash
на /bin/sh
, чтобы посмотреть, было ли это bash
-специфическая вещь, но это не имело никакого значения.
Яработает Python 3.5.2.Что может быть причиной поведения, которое я вижу?Почему чтение только работает после закрытия стандартного ввода, но не перенаправления stdout
работает просто отлично?Я просто не могу понять поведение, которое вижу, и не могу воспроизвести с помощью других команд.Я понимаю, что, возможно, я мог бы использовать один из представленных новых асинхронных API, но я действительно хочу понять, что может быть корнем этого поведения.Обратите внимание, что в ответ на ls
отправляется очень небольшое количество данных, поэтому оно, конечно, не заполняется до полной емкости.