LINUX.ORG.RU

перенаправление потоков в python

 ,


1

2

надо наладить конвейер фильтров на python, типа

./curl.py | ./parse.py | ./download.py

но видимо что-то делаю не так. когда делаю ./parse.py | tail -f

то ./parse.py вылетает с ошибкой I/O operation on closed file.

в нём вывожу данные вот так:

sys.stdout.write(teststr + "\n")
sys.stdout.flush()

очевидно, что при использовании | , sys.stdout закрывается и открывается pipe

но не понятно где его найти и как туда писать

вот, висит

python -c "while True:__import__('sys').stdout.write('test test\n')" | tail -f

★★★

Последнее исправление: fMad (всего исправлений: 1)
Ответ на: комментарий от fMad

Короче, проблема в том, что tail помирает, не дождавшись ввода. Вот такой вот костыль работает:

python -c "while True:print('test test\n')" && sleep 1 | tail -f

Но подожди еще, может, чего-нибудь более изящного насоветуют.

WizardOfOz
()
Ответ на: комментарий от fMad

tail -f

Так вообще можно? И какой в этом смысл? Если использовать strace то видно что проблема не в питоне. Ты лучше расскажи какая задача стоит.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Не, тут не в буферизации дело - он же флашит stdout в первом примере.

WizardOfOz
()

команда_генерации_бесконченого_потока | tail -f

ничего не отображает, поскольку tail ждёт конца потока прежде чем начать отображать.

А python -c «while True:print('test test\n')» && sleep 1 | tail -f

вообще не запускает ни sleep ни tail пока скрипт не завершится.

Короче tail -f - это неудачный выбор для тестирования pipe-ов для которых предполагется постоянная динамическая передача данных.

GPFault ★★
()
Ответ на: комментарий от true_admin

ну смотри, обычное, мне надо с помощью | перенаправлять потоки данных от разных python скриптов, так же как мы это делаем с обычными cli прогарммами

fMad ★★★
() автор топика
Ответ на: комментарий от fMad

мне надо с помощью | перенаправлять потоки данных от разных python скриптов

Оно работает так как и ожидается. Никакого магии кроме буферизации (за которой я отправил в гугл) и кодировок (превед, пистон3) нет. Если ты считаешь что проблема то сделай минимальный рабочий пример. Твой пример с tail -f некорректен потому что там затык в tail.

true_admin ★★★★★
()
Ответ на: комментарий от fMad

В файле в каждый момент времени есть понятие размера, который определяет его конец. Если файл дозаписывается - конец сдвигается. Поэтому tail -f делает снепшот конца файла и потом постоянно его обновляет.

А в pipe - нет понятия текущего размера. Поэтому «снепшот конца» можно получить только тогда, когда в pipe больше не пишут.

GPFault ★★
()
#!/usr/bin/python3

import sys

d = True
while d:
    d = sys.stdin.buffer.read(1)
    sys.stdout.buffer.write(d)
    sys.stdout.buffer.flush()
@> echo "Hello cruel world" | ./inout.py | ./inout.py
Hello
anonymous
()
Ответ на: комментарий от fMad

tail -f не ждёт, иначе как бы он читал файлы

Набери yes | tail -f и убедись сам.

proud_anon ★★★★★
()

то ./parse.py вылетает с ошибкой I/O operation on closed file.

А ты уверен, что дело не в чтении из curl?

очевидно, что при использовании | , sys.stdout закрывается и открывается pipe

Нет, это совсем не так. sys.stdout у тебя работает как обычно и выводит в этот файл.

вот, висит

Из-за tail -f.

proud_anon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.