Есть ли способ вывести конвейерную строку из текущей программы python?

при конвейерной печати вывода из скрипта python в команду, такую как grep, вывод из скрипта, по-видимому, передается только команде последующих действий после завершения всего скрипта.

например, в скрипте test_grep.py следующим образом:

#!/usr/bin/env python
from time import sleep

print "message1"
sleep(5)
print "message2"
sleep(5)
print "message3"

при вызове с ./test_grep.py | grep message ничего не появится в течение 10 секунд, когда все три линии появится.

сравните это со сценарием test_grep.sh:

#!/usr/bin/env bash
echo "message1"
sleep 5 
echo "message2"
sleep 5
echo "message3"

./test_grep.sh | grep message будет сразу же выход message1, а затем с интервалом в 5 секунд message2 и message3.

Я ожидаю, что это связано с тем, что только после завершения выполнения интерпретатора python Вывод доступен для следующей команды. Есть ли способ изменить это поведение?

1 ответов


вы можете сделать это:

  • топить каждый print в python
  • , установив stdout быть unbuffered
  • установив stdout для буферизации строк

вы даже можете позвонить python -u для отключения буферизации.


Я бы пошел на вариант буферизации строк, поскольку это кажется наиболее естественным.

open(file, mode='r', buffering=-1 ....)

buffering-необязательное целое число, используемое для установки политики буферизации. Передайте 0 для переключения буферизации off (разрешено только в двоичном режиме),1 к выберите буферизация строк (использовать только в текстовом режиме), и целое число > 1 чтобы указать размер буфера chunk фиксированного размера.

когда вы не указываете буферизацию (типичную "открытую"), она будет использовать буферизацию строк, если она обнаружит, что вывод идет непосредственно на TTY, т. е. на вашу экранную консоль. Если вы передадите вывод или перенаправите его в файл, он переключится обратно в большой буфер (4K / 8K).


как вы "устанавливаете stdout для линейной буферизации"?

вы можете открыть stdout via sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1).