Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 29, 2016 01:12:25

Mr.Anderson
Зарегистрирован: 2015-02-06
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

Суть проблемы такая, есть скрипт из которого запускается сторонний скрипт. Но этот сторонний скрипт просит несколько раз вести 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')

Офлайн

#2 Сен. 29, 2016 01:24:25

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

Не используйте communicate. Вы можете вызывать

  sp = subprocess.Popen(...)
затем используя sp.stdin.write(…) писать в поток ввода неоднократно. Можно считывать sp.stdout что бы распарсить вывод дочерней программы и в нужном месте писать в поток ввода



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Сен. 29, 2016 04:23:10

Mr.Anderson
Зарегистрирован: 2015-02-06
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

все равно, при первой же попытке виснет

 sp = subprocess.Popen(['sqlmap -u ' + '"' + site + '"' + ' --dbs'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
sp.stdin.write(b'Y')
Когда использовал communicate по крайней мере в первый раз строка отсылалась.

Офлайн

#4 Сен. 29, 2016 07:26:28

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

для этого предназначен pexpect. Если он не работает то покажите как вы это делали. Если pexpect не может то скорее всего вам ничто не поможет.

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

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

p.s.
Абсолютно очевидно write(“Y”) недостаточно. ВЫ же реально enter нажимаете? почему вы перевод строки не отослали?



Отредактировано doza_and (Сен. 29, 2016 07:37:59)

Офлайн

#5 Сен. 30, 2016 21:50:14

Mr.Anderson
Зарегистрирован: 2015-02-06
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

Вопрос закрыт, решение нашел.
нудно было дополнить кое что, после вызова метода stdin.write('Y'), нудно было его закрыть методом stdin.close(), и тогда работает все как надо. Спасибо за помощь и советы.

Офлайн

#6 Сен. 30, 2016 22:57:12

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

Не надо было так делать. Давайте я вам на конкретном примере покажу как надо было. Напишем консольную программу, которая будет ожидать неоднократный ввод данных от пользователя:

 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 (вы в своем примере добились этого закрытием потока, но это одноразовая мера). В итоге все правильно отрабатывает.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#7 Сен. 30, 2016 23:00:20

Mr.Anderson
Зарегистрирован: 2015-02-06
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

Как послать communicate несолько раз?

JOHN_16
Не надо было так делать. Давайте я вам на конкретном примере покажу как надо было. Напишем консольную программу, которая будет ожидать неоднократный ввод данных от пользователя:
Спасибо, за подробный ответ, я приму к сведению)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version