Найти - Пользователи
Полная версия: Как послать communicate несолько раз?
Начало » Python для экспертов » Как послать communicate несолько раз?
1
Mr.Anderson
Суть проблемы такая, есть скрипт из которого запускается сторонний скрипт. Но этот сторонний скрипт просит несколько раз вести Y. С первым разом все впорядке, communicate(input=b'Y') выполняет задачу, после этого нужно сразу же послать еще один такой же communicate(input=b'Y'). Как это сделать?
Решения с помощью pexpect не подходит, пробовал уже.
Вот сам вызов процесса
 out, err = Popen('sqlmap -u ' + '"' + site + '"' + ' --dbs', shell=True, stdin=PIPE, stdout=PIPE).communicate(input=b'Y')
JOHN_16
Не используйте communicate. Вы можете вызывать
  sp = subprocess.Popen(...)
затем используя sp.stdin.write(…) писать в поток ввода неоднократно. Можно считывать sp.stdout что бы распарсить вывод дочерней программы и в нужном месте писать в поток ввода
Mr.Anderson
все равно, при первой же попытке виснет
 sp = subprocess.Popen(['sqlmap -u ' + '"' + site + '"' + ' --dbs'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
sp.stdin.write(b'Y')
Когда использовал communicate по крайней мере в первый раз строка отсылалась.
doza_and
для этого предназначен pexpect. Если он не работает то покажите как вы это делали. Если pexpect не может то скорее всего вам ничто не поможет.

Если вы управляете скриптом на питоне то правильнее будет заглянуть внутрь найти нужные фукнкции импортировать в свой скрипт и использовать (Или посмотреть документацию по АПИ). То что вы делаете напоминает удаление гландов через ж… :). Управление через pexct это крайнее средство.

Вообще нормально построенный скрипт не должен просить подтверждений. Посоветую вам поменять его или вообще сменить инструментарий.

p.s.
Абсолютно очевидно write(“Y”) недостаточно. ВЫ же реально enter нажимаете? почему вы перевод строки не отослали?
Mr.Anderson
Вопрос закрыт, решение нашел.
нудно было дополнить кое что, после вызова метода stdin.write('Y'), нудно было его закрыть методом stdin.close(), и тогда работает все как надо. Спасибо за помощь и советы.
JOHN_16
Не надо было так делать. Давайте я вам на конкретном примере покажу как надо было. Напишем консольную программу, которая будет ожидать неоднократный ввод данных от пользователя:
 john_16@Linux-home ~/bin $ cat one.py 
print('Enter X:')
x = input()
print('Enter Y:')
y = input()
print('x + y = {}'.format(sum(map(int, (x, y)))))
Убедимся что она работаем именно так:
 john_16@Linux-home ~/bin $ python3 one.py 
Enter X:
1
Enter Y:
2
x + y = 3
Теперь напишем программу которая будет вызывать эту программу:
 john_16@Linux-home ~/bin $ cat two.py 
from subprocess import Popen, PIPE
sp = Popen('python3 one.py', shell=True, stdout=PIPE, stdin=PIPE)
for value in sp.stdout:
    print('Get line: {}'.format(value))
    if b'Enter' in value:
        print('Send value')
        sp.stdin.write(b'2\n')
        sp.stdin.flush()
print('Finish')
И убедимся что она работает и делает в общем то то что надо:
 john_16@Linux-home ~/bin $ python3 two.py 
Get line: b'Enter X:\n'
Send value
Get line: b'Enter Y:\n'
Send value
Get line: b'x + y = 4\n'
Finish
Теперь разберем как она работает - вызываем дочернюю программу, в цикле считываем построчный вывод, если находим в строке приглашение к вводу данных - и в этом случае вводим пользовательские данные. Для этого не забываем включить в ввод символ переноса строки \n. Так же стоит учесть что входной поток данных буферизирован, поэтому после ввода данных явно сбрасываем буффер методом flush (вы в своем примере добились этого закрытием потока, но это одноразовая мера). В итоге все правильно отрабатывает.
Mr.Anderson
JOHN_16
Не надо было так делать. Давайте я вам на конкретном примере покажу как надо было. Напишем консольную программу, которая будет ожидать неоднократный ввод данных от пользователя:
Спасибо, за подробный ответ, я приму к сведению)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB