Как проверить, есть ли в 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()