Python - Как я передаю строку в подпроцесс. Popen (использующий stdin аргумент)?

Статья в блоге, приведенная в других ответах, не совсем корректна. Дело не только в том, что вы не выполняете трехстороннее рукопожатие, а в том, что IP-стек ядра не знает, что происходит соединение. Когда он получает SYN-ACK, он отправляет RST-ACK, потому что это неожиданно. Получение первого или последнего действительно не входит в него. Стек , получающий SYN-ACK, является проблемой.

Использование IPTables для удаления исходящих пакетов RST - это общий и действительный подход, но иногда вам нужно отправить RST от Scapy. Более сложный, но очень эффективный подход заключается в том, чтобы идти ниже, генерируя и реагируя на ARP с MAC, который отличается от хоста. Это позволяет вам иметь возможность отправлять и получать что угодно без каких-либо помех от хоста.

Очевидно, что это больше усилий. Лично я использую этот подход (в отличие от подхода RST dropping), когда мне действительно нужно отправить сам RST.

263
задан Nikhil Chelliah 4 June 2009 в 15:56
поделиться

4 ответа

Popen.communicate() документация:

Примечание, что, если Вы хотите отправить данные в process’s stdin, необходимо создать объект Popen с stdin=PIPE. Точно так же для получения чего-либо ни кроме Одного в кортеже результата необходимо дать stdout=PIPE и/или stderr=PIPE также.

Замена os.popen*

    pipe = os.popen(cmd, 'w', bufsize)
    # ==>
    pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin

Предупреждение Использование связываются (), а не stdin.write (), stdout.read () или stderr.read () для предотвращения мертвых блокировок из-за любого из других буферов канала ОС, заполняющихся и блокирующихся дочерний процесс.

, Таким образом, Ваш пример мог быть записан следующим образом:

from subprocess import Popen, PIPE, STDOUT

p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)    
grep_stdout = p.communicate(input=b'one\ntwo\nthree\nfour\nfive\nsix\n')[0]
print(grep_stdout.decode())
# -> four
# -> five
# ->
<час>

На текущей версии Python 3, Вы могли использовать subprocess.run , чтобы передать вход как строку к внешней команде и получить ее статус выхода и ее вывод как строка назад в одном вызове:

#!/usr/bin/env python3
from subprocess import run, PIPE

p = run(['grep', 'f'], stdout=PIPE,
        input='one\ntwo\nthree\nfour\nfive\nsix\n', encoding='ascii')
print(p.returncode)
# -> 0
print(p.stdout)
# -> four
# -> five
# -> 
310
ответ дан jfs 23 November 2019 в 02:33
поделиться

Я выяснил это обходное решение:

>>> p = subprocess.Popen(['grep','f'],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
>>> p.stdin.write(b'one\ntwo\nthree\nfour\nfive\nsix\n') #expects a bytes type object
>>> p.communicate()[0]
'four\nfive\n'
>>> p.stdin.close()

там лучший?

45
ответ дан tobsecret 23 November 2019 в 02:33
поделиться

"По-видимому, объект cStringIO.StringIO не делает шарлатана достаточно близко утке файла для удовлетворения подпроцессу. Popen"

:-)

я боюсь нет. Канал является понятием ОС низкого уровня, таким образом, он абсолютно требует объекта файла, который представлен дескриптором файла уровня ОС. Ваше обходное решение является правильным.

13
ответ дан Dan Lenski 23 November 2019 в 02:33
поделиться
p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)    
p.stdin.write('one\n')
time.sleep(0.5)
p.stdin.write('two\n')
time.sleep(0.5)
p.stdin.write('three\n')
time.sleep(0.5)
testresult = p.communicate()[0]
time.sleep(0.5)
print(testresult)
3
ответ дан 23 November 2019 в 02:33
поделиться
Другие вопросы по тегам:

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