Как проверить, есть ли в stdin какие-либо данные?

В Python, как вы проверяете, если sys.stdin есть данные или нет?

я нашел это os.isatty(0) может не только проверить, подключен ли stdin к устройству TTY, но также есть доступные данные.

Но если кто-то использует такой код, как

sys.stdin = cStringIO.StringIO("ddd")

и после этого использует os.isatty(0), он все еще возвращает True. Что мне нужно сделать, чтобы проверить, есть ли в stdin данные?

7 ответов

Решение

В системах Unix вы можете делать следующее:

import sys
import select

if select.select([sys.stdin,],[],[],0.0)[0]:
    print "Have data!"
else:
    print "No data"

В Windows модуль select можно использовать только с сокетами, хотя вам придется использовать альтернативный механизм.

Я использую

if not sys.stdin.isatty()

Вот пример:

4 import sys
5
6 def main():
7     if not sys.stdin.isatty():
8         print "not sys.stdin.isatty"
9     else:
10         print "is  sys.stdin.isatty"

>echo "asdf" | stdin.py
not sys.stdin.isatty

sys.stdin.isatty () возвращает false, если что-то есть в stdin.

isatty(...)
    isatty() -> true or false. True if the file is connected to a tty device.

В зависимости от цели здесь:

import fileinput
for line in fileinput.input():
    do_something(line)

также может быть полезным.

(редактировать: это ответ на связанный вопрос, который с тех пор был объединен здесь.)

Как уже упоминалось, нет надежного способа узнать, будут ли данные доступны из stdin, потому что UNIX не позволяет этого (и в более общем плане, потому что не может угадать будущее поведение программы, к которой подключается stdin).

Всегда жди stdin, даже если ничего не может быть (вот что grep и т.д.), или попросить пользователя - аргумент.

Выше видел множество ответов, в которых почти все ответы требовали sys, select, os и т. Д. Тем не менее, у меня возникла очень простая идея о том, как непрерывно принимать ввод от stdin, если он имеет данные. Для этого мы можем использовать try, except block. в качестве,

      while(1):
  try:
    inp = input()
  except:
     break

Вышеупомянутый цикл будет запущен, и мы постоянно проверяем ввод и сохраняем ввод в переменной "inp", если в stdin нет ввода, тогда try выдает ошибку, однако в except есть оператор break, поэтому цикл while будет быть прекращено

Я нашел способ использовать будущее из библиотеки concurrent.futures. Это программа с графическим интерфейсом, которая позволит вам прокручивать и нажимать кнопку ожидания, когда вы все еще ждете стандартного ввода. Всякий раз, когда программа видит, что у нее есть строка информации из STDIN, она печатает ее в многострочном поле. Но это не блокирует скрипт, блокирующий пользователя от интерфейса графического интерфейса, почему он проверяет стандартный ввод на наличие новой строки. (Обратите внимание, что я тестировал это в python 3.10.5)

введите код сюда

      import concurrent.futures
import PySimpleGUI as sg
import sys

def readSTDIN():
    return sys.stdin.readline()

window = sg.Window("Test Window", [[sg.Multiline('', key="MULTI", size=(40, 10))],
                                   [sg.B("QUIT", bind_return_key=True, focus=True),
                                    sg.B("Wait")]], finalize=True, keep_on_top=True)
for arg in sys.argv[1:]:
    window["MULTI"].print(f"ARG={arg}")
with concurrent.futures.ThreadPoolExecutor() as pool:
    futureResult = pool.submit(readSTDIN)
    while True:
        event, values = window.read(timeout=500)
        if event != "__TIMEOUT__":
            window['MULTI'].print(f"Received event:{event}")
        if event in ('QUIT', sg.WIN_CLOSED):
            print("Quit was pressed")
            window.close()
            break
        if futureResult.done(): # flag that the "future" task has a value ready;
                                #therefore process the line from STDIN
            x = futureResult.result()
            window["MULTI"].print(f"STDIN:{x}")
            futureResult = pool.submit(readSTDIN) #add a future for next line of STDIN

Используя встроенные модули, это может быть достигнуто с помощью следующего кода, поскольку Грег уже высказал идею:

import fileinput
isStdin = True
for line in fileinput.input:
    # check if it is not stdin
    if not fileinput.isstdin():
        isStdin = False
        break
    # continue to read stdin
    print(line)
fileinput.close()


Другие вопросы по тегам