Python для непрерывного чтения стандартного ввода из другого источника

Можно ли позволить Python постоянно читать из стандартного ввода из другого источника, например из файла? По сути, я пытаюсь разрешить своему сценарию использовать стандартный ввод для эхо-ввода, и я хотел бы использовать файл или внешний источник для взаимодействия с ним (оставаясь при этом открытым).

Примером может быть (input.py):

#!/usr/bin/python

import sys

line = sys.stdin.readline()

while line:
    print line,
    line = sys.stdin.readline()

Выполняя это напрямую, я могу непрерывно вводить текст, и он возвращается, пока скрипт остается живым. Если вы хотите использовать внешний источник, такой как файл или ввод из bash, скрипт завершает работу сразу после получения ввода:

$ echo "hello" | python input.py
hello
$

В конечном итоге я хотел бы сделать следующее:

$ tail -f file | python input.py

Затем, если обновления файла имеют input.py, отобразите все, что добавлено в файл, оставаясь при этом открытым. Может быть, я подхожу к этому неправильно или я просто невежественен, но есть ли способ сделать это?


person Rory Zipher    schedule 03.02.2016    source источник
comment
Так ты пробовал это? Если это не работает, возможно, вы столкнулись с проблемой буферизации - посмотрите   -  person TNW    schedule 04.02.2016
comment
Он читает файл, но если я обновлю файл, изменения не отразятся в stdin/stdout python.   -  person Rory Zipher    schedule 04.02.2016
comment
tail -f file будет продолжать выдавать данные, добавленные к файлу. Обновления, добавленные в файл, работают... вы делаете это как-то по-другому?   -  person tdelaney    schedule 04.02.2016
comment
@RoryZipher Tail будет следовать только в том случае, если файл добавлен, а не изменен. Так что не то, что бы вы сделали, скажем, vim. Попробуйте echo "stuff" >> file проверить это.   -  person TNW    schedule 04.02.2016
comment
Да, я добавляю файл. например, если файл содержит привет, тогда я запускаю команду, добавляю файл в следующую строку с миром и сохраняю его, он не отображается в stdin/stdout текущего исполняемого процесса.   -  person Rory Zipher    schedule 04.02.2016
comment
Так что, вероятно, проблема с буферизацией, потому что она отлично работает для меня, как вы ее предоставили. Имейте в виду, что под добавлением я подразумеваю, что файл должен быть открыт с O_APPEND в параметрах open.   -  person TNW    schedule 04.02.2016
comment
Да, я думаю, вы правы. Выполнение echo "something else" >> file работает нормально, но если я использую внешний редактор и сохраняю его, он, похоже, игнорирует его.   -  person Rory Zipher    schedule 04.02.2016
comment
Редактор может создавать новый файл вместо того, чтобы перезаписывать исходный файл. Попробуйте использовать tail -F -f file. Это снова откроет файл, если он будет переименован.   -  person Barmar    schedule 04.02.2016
comment
@Barmar прав, редакторы обычно записывают во временный файл, а затем перезаписывают существующий файл при сохранении.   -  person tdelaney    schedule 04.02.2016
comment
@tdelaney Это не вызовет этой проблемы. Я предлагаю им записать во временный файл и переименовать его в исходное имя файла. Так Emacs работает по умолчанию, хотя у него есть переменные настройки, которые его изменяют.   -  person Barmar    schedule 04.02.2016
comment
@Barmar: Да, это работает, но с одной оговоркой ... Мне нужно вставить разрыв строки, чтобы прочитать добавленный текст, иначе он не будет обновляться. Ничего страшного, так как я мог бы включить разрыв строки. Если вы хотите поместить свой комментарий в качестве ответа, я с радостью приму его - спасибо!   -  person Rory Zipher    schedule 04.02.2016


Ответы (1)


Используйте параметр -F для tail, чтобы повторно открыть файл, если он будет переименован или удален, и будет создан новый файл с исходным именем. Некоторые редакторы записывают файл таким образом, и сценарии ротации лог-файлов также обычно работают таким образом (они переименовывают исходный файл в filename.1 и создают новый лог-файл).

$ tail -F file | python input.py
person Barmar    schedule 03.02.2016
comment
Это не сработало на моем Linux Mint, и я немного удивлен, что tail даже принял как -F, так и -f, что говорит ему следовать по имени и дескриптору файла. Но tail -f F file | python input.py сработало. Вы имели в виду только tail -F file | python input.py? - person tdelaney; 04.02.2016
comment
Я неправильно прочитал документацию, я думал, что -F изменил поведение -f, а не альтернативу. - person Barmar; 04.02.2016