Ввод трубы в программу Python и последующий ввод данных от пользователя

Предположим, я хочу подключить вход к программе Python, а затем получить входную информацию от пользователя в командной строке.

echo http://example.com/image.jpg | python solve_captcha.py 

и содержимое solve_captcha.py :

 import sys image_url = sys.stdin.readline() # Download and open the captcha... captcha = raw_input("Solve this captcha:") # do some processing... 

Вышеупомянутое вызовет EOFError: EOF when reading a line ошибки.

Я также попытался добавить sys.stdin.close() , которая вызвала ValueError: I/O operation on closed file .

Можете ли вы передавать информацию на stdin а затем позже вводить информацию от пользователя?

Примечание. Это упрощенный пример, пожалуйста, не отвечайте, говоря «почему вы хотите сделать это в первом случае», это действительно расстраивает. Я просто хочу знать, можно ли передавать информацию на stdin а затем запрашивать пользователя для ввода.

  • Как вы передаете данные в STDIN программы из разных локальных / удаленных процессов в Python?
  • Передача данных между Python и C # без записи файла
  • Отправка строк между скриптами Python с использованием подпроцессов PIPE
  • Twisted Python: не удается выполнить запись в запущенный порожденный процесс
  • Имя файла Python stdin
  • Несколько входов и выходов в подпроцессе python
  • Общайтесь с подпроцессом, не дожидаясь завершения подпроцесса в окнах
  • Установка меньшего размера буфера для sys.stdin?
  • 4 Solutions collect form web for “Ввод трубы в программу Python и последующий ввод данных от пользователя”

    Нет общего решения этой проблемы. Лучшим ресурсом, похоже, является этот список рассылки .

    В принципе, соединение в программу соединяет stdin программы с этим каналом, а не с терминалом.

    В потоке списка рассылки есть несколько относительно простых решений для * nix:

    Открыть / dev / tty для замены sys.stdin:

     sys.stdin = open('/dev/tty') a = raw_input('Prompt: ') 

    Перенесите stdin в другой дескриптор файла при запуске скрипта и прочитайте с него:

     sys.stdin = os.fdopen(3) a = raw_input('Prompt: ') $ (echo -n test | ./x.py) 3<&0 

    а также предложение использовать проклятия . Обратите внимание, что поток списка рассылки является древним, поэтому вам может потребоваться изменить выбранное решение.

    bash имеет замену процесса, которая создает FIFO, который вы можете рассматривать как файл, поэтому вместо

     echo http://example.com/image.jpg | python solve_captcha.py 

    вы можете использовать

     python solve_capcha.py <(echo http://example.com/image.jpg) 

    Вы должны открыть первый аргумент для файла solve_capcha.py в качестве файла, и я думаю, что sys.stdin все равно будет доступен для чтения ввода с клавиатуры.

    Сделал это для эмуляции raw_input() , так как у меня была такая же проблема, как и вы. Весь stdin и clear уродство – просто заставить его выглядеть красиво. Чтобы вы могли видеть, что вы печатаете.

     def getInputFromKeyPress(promptStr=""): if(len(promptStr)>0): print promptStr """ Gets input from keypress until enter is pressed """ def clear(currStr): beeString, clr="","" for i in range(0,len(currStr)): clr=clr+" " beeString=beeString+"\b" stdout.write(beeString) stdout.write(clr) stdout.write(beeString) from msvcrt import kbhit, getch from sys import stdout resultString, userInput="", "" while(userInput!=13): if (kbhit()): charG=getch() userInput= ord(charG) if(userInput==8):#backspace resultString=resultString[:-1] clear(resultString) elif(userInput!=13): resultString="".join([resultString,charG]) clear(resultString) stdout.write(resultString) if(userInput==13): clear(resultString) #print "\nResult:",resultString return resultString.strip() в def getInputFromKeyPress(promptStr=""): if(len(promptStr)>0): print promptStr """ Gets input from keypress until enter is pressed """ def clear(currStr): beeString, clr="","" for i in range(0,len(currStr)): clr=clr+" " beeString=beeString+"\b" stdout.write(beeString) stdout.write(clr) stdout.write(beeString) from msvcrt import kbhit, getch from sys import stdout resultString, userInput="", "" while(userInput!=13): if (kbhit()): charG=getch() userInput= ord(charG) if(userInput==8):#backspace resultString=resultString[:-1] clear(resultString) elif(userInput!=13): resultString="".join([resultString,charG]) clear(resultString) stdout.write(resultString) if(userInput==13): clear(resultString) #print "\nResult:",resultString return resultString.strip() 

    Я обновил @ ответ Боба, чтобы помочь удалить, ctrl + [left, right, home, end] нажатия клавиш и упростить очистку и переписывание stdout.

     def keypress_input(prompt_str=""): """ Gets input from keypress using `msvcrt` until enter is pressed. Tries to emulate raw_input() so that it can be used with piping. :param prompt_str: optional string to print before getting input :type prompt_str: str """ from re import finditer from msvcrt import getch from sys import stdout # print even if empty to create new line so that previous line won't be overwritten if it exists print prompt_str user_input = "" curr_chars = [] cursor_pos = 0 backspace = 8 enter = 13 escape_code = 224 delete = 83 left = 75 right = 77 home = 71 end = 79 ctrl_left = 115 ctrl_right = 116 ctrl_home = 119 ctrl_end = 117 while user_input != enter: char_g = getch() user_input = ord(char_g) prev_len = len(curr_chars) # track length for clearing stdout since length of curr_chars might change if user_input == backspace: if len(curr_chars) > 0 and cursor_pos <= len(curr_chars): cursor_pos -= 1 curr_chars.pop(cursor_pos) elif user_input == escape_code: user_input = ord(getch()) if user_input == delete: curr_chars.pop(cursor_pos) elif user_input == left: cursor_pos -= 1 elif user_input == right: if cursor_pos < len(curr_chars): cursor_pos += 1 elif user_input == home: cursor_pos = 0 elif user_input == end: cursor_pos = len(curr_chars) elif user_input == ctrl_home: curr_chars = curr_chars[cursor_pos:] cursor_pos = 0 elif user_input == ctrl_end: curr_chars = curr_chars[:cursor_pos] cursor_pos = len(curr_chars) elif user_input == ctrl_left: try: chars_left_of_cursor = "".join(curr_chars[:cursor_pos]) left_closest_space_char_index = [m.span()[0] for m in finditer(" \w", chars_left_of_cursor)][-1] pos_diff = cursor_pos - left_closest_space_char_index - 1 cursor_pos -= pos_diff except IndexError: cursor_pos = 0 elif user_input == ctrl_right: try: chars_right_of_cursor = "".join(curr_chars[cursor_pos + 1:]) right_closest_space_char_index = [m.span()[0] for m in finditer(" \w", chars_right_of_cursor)][0] cursor_pos += right_closest_space_char_index + 2 except IndexError: cursor_pos = len(curr_chars) - 1 elif user_input != enter: if cursor_pos > len(curr_chars) - 1: curr_chars.append(char_g) else: curr_chars.insert(cursor_pos, char_g) cursor_pos += 1 # clear entire line, write contents of curr_chars, reposition cursor stdout.write("\r" + prev_len * " " + "\r") stdout.write("".join(curr_chars)) pos_diff = len(curr_chars) - cursor_pos stdout.write("\b" * pos_diff) stdout.write("\r" + len(curr_chars) * " " + "\r") stdout.write("".join(curr_chars) + "\n") return "".join(curr_chars) 
    Python - лучший язык программирования в мире.