Время, затраченное командой `less`, чтобы показать вывод - PullRequest
5 голосов
/ 08 мая 2011

У меня есть скрипт, который производит много выходных данных. Скрипт останавливается на несколько секунд в точке T.

Теперь я использую команду less для анализа вывода скрипта. Поэтому я выполняю ./script | less. Я оставляю его включенным в течение достаточного времени, чтобы скрипт завершил выполнение.

Теперь я просматриваю вывод команды less, нажимая клавишу Pg Down. Удивительно, когда при прокрутке в точке T выхода я снова вижу паузу в несколько секунд.

Скрипт не ожидает ввода и определенно завершится к тому времени, когда я начну анализировать вывод less.

Может кто-нибудь объяснить, как пауза в несколько секунд заметна в выводе команды less, когда сценарий завершится?

Ответы [ 5 ]

8 голосов
/ 08 мая 2011

Ваш скрипт взаимодействует с less через канал .Канал представляет собой поток байтов в памяти, который соединяет две конечные точки: ваш скрипт и программу less, первый из которых записывает выходные данные, а второй читает из него.

Поскольку каналы находятся в памяти, онбыло бы не приятно, если бы они росли сколь угодно большими.Таким образом, по умолчанию существует предел данных, которые могут быть внутри канала (записаны, но еще не прочитаны) в любой данный момент.По умолчанию это 64 КБ в Linux.Если канал заполнен, и ваш сценарий пытается выполнить запись, запись блокируется.Итак, ваш скрипт на самом деле не работает, в какой-то момент он остановился при write() вызове .

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

Так что бы решитьпроблема заключается в чтении файла до конца (как обычно вы нажимаете G ), а затем возвращении к началу (как обычно вы нажимаете g ).Дело в том, что вы можете указывать эти команды через командную строку следующим образом:

./script | less +Gg

Однако вы должны заметить, что вам придется ждать, пока весь вывод скрипта загрузится в память, поэтому вы не будетебыть в состоянии просмотреть это сразу.less недостаточно сложен для этого.Но если это именно то, что вам действительно нужно (просматривая начало вывода, пока ./script все еще вычисляет его конец), вы можете использовать временный файл:

 ./script >x & less x ; rm x
2 голосов
/ 08 мая 2011

Для некоторой справочной информации есть также хорошая статья Александра Сэндлера под названием "Как меньше обрабатывает свой ввод"!

http://www.alexonlinux.com/how-less-processes-its-input

2 голосов
/ 08 мая 2011

Контроль потока.Ваш сценарий фактически приостанавливается, в то время как «подкачка меньше».

Если вы хотите убедиться, что ваша команда завершается до того, как вы используете менее интерактивно, вызовите less как less +G, и она будет читать до конца вводазатем вы можете вернуться к началу, набрав 1G в меньше.

2 голосов
/ 08 мая 2011

Канал заполнен на уровне операционной системы, поэтому script блокируется до тех пор, пока less не израсходует часть.

0 голосов
/ 22 января 2013
Can I externally enforce line buffering on the script? 
Is there an off the shelf pseudo tty utility I could use? 

Вы можете попробовать использовать команду script для включения режима вывода с буферизацией строки.

script -q /dev/null ./script | less      # FreeBSD, Mac OS X
script -c "./script" /dev/null | less    # Linux

Для получения дополнительной информации об этом см. Отключите буферизацию в трубе .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...