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

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

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

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

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

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

Ответ 1

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

import sys
import select

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

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

Ответ 2

Я использовал

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.

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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()