Как уже писал Нулман в комментарии, лучше проверить параметры командной строки, чтобы решить, хотите ли вы попробовать stdin
или нет.
Краткое резюме: Вы не можете с уверенностью предположить, следует ли вам читать данныеот stdin
проверяя stdin
.Вы должны полагаться только на проверку командной строки, чтобы выяснить, что ожидается.
Например, cat
будет использовать stdin
, только если входной файл не был указан в качестве аргумента командной строки или если специальное имя файла-
было указано.
Все тесты в ваших примерах будут работать только в определенных условиях и не будут работать в других случаях.
Проверка того, является ли stdin
TTY, выполняетсянет помощи.Он только скажет вам, если он подключен к терминалу.Ваш сценарий может получать входные данные от терминала, если пользователь что-то печатает или это псевдо-терминал, подключенный к чему-то другому.Ваш скрипт также может получать данные от stdin
, если он подключен не к терминалу, а к чему-то другому (канал, файл, сокет, ...)
Проверка, является ли stdin
FIFO, также невернапотому что вы можете читать данные как из pipe / fifo, так и из чего-то еще (файл, сокет, терминал, ...).
Использование select
не скажет вам, есть ли какие-либо данные, но только еслиread
не будет блокировать.Это также не будет блокировать на EOF.Чтобы отличить эти случаи, вы должны проверить результат read
из stdin
.Без задержки / тайм-аута он также может сказать вам, что read
заблокируется, если данные еще не доступны.
Есть и другие способы использования сценария:
Вместо cat myInput | ./myscript.py
вы также можете использовать ./myscript.py < myInput
.В первом случае stdin
будет труба, во втором случае файл.
Или представьте ./myscript.py < /dev/null
.Это вернет условие EOF для первого read
.
или ./myscript.py <&-
, которое закроет stdin
, что приведет к ошибке при попытке чтения из него.
Если stdin
подключен ктерминал, который read
может заблокировать, если пользователь ничего не вводит.Это произойдет, если вы позвоните ./myscript.py
.Вы можете использовать select
, чтобы узнать, доступны ли данные сейчас , но вы не можете узнать, введет ли пользователь данные позже.Таким образом, ваш сценарий не знает намерения пользователя.