Буферизация FIFO в Linux зависит от порядка вызова модулей чтения и записи.

$ awk -vOFS='\t' '{ print length($1), $0 }' file.in | sort -k1,1n -k2,2 | cut -f2-
.fe is bla bla bla
.se is for swedish domains
.abc is bla se 23 bla
.abs is bla bla 12
.jpg is pic extension

Это сортирует файл file.inпо длине данных в первом столбце, затем лексикографически по фактическим данным первого столбца (это не было специально запрошено в вопросе, но дает приятный штрих к результат ).

Код awkсоздаст вывод табуляции -с разделителями, например

4      .abs is bla bla 12
4      .abc is bla se 23 bla
3      .fe is bla bla bla
4      .jpg is pic extension
3      .se is for swedish domains

и это то, что sortсортирует по первому столбцу (численно ), а затем по второму столбцу (лексикографически ). Затем cutудаляет из него первый столбец.

0
26.09.2019, 15:16
1 ответ

Вы неправильно использовали tail.

То, что вы заметили, является просто признаком того, чтоtail -f outputработает так, как рекламируется . И есть еще подводные камни в вашем tail -f inputиспользовании.

Обратите внимание, что эти tailзлоупотребления также нарушат работоспособность вашего скрипта. Подробнее см. ниже...

Краткое пояснение

Проблемы с вашим tail -f inputиспользованием:

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

Проблемы с tail -f outputиспользованием:

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

(Буферизация не является проблемой в tail -f output, так как его выходная ветвь является терминалом )

.

См. Заключение ниже для средств правовой защиты.

Подробное объяснение

Описание задания tailпо сути :"выводит 10 строк, которые находятся непосредственно перед концом -файла -". Переключатель -fдобавляет только «и все, что впоследствии было добавлено к нему ».

  • Чтобы достичь своей основной цели, tailдолжен продолжать считывать ввод, молча и бесконечно (с сохранением только последних 10 строк в буфере ), пока не будет достигнут конец -из -. Затем он выгружает последние 10 строк из буфера в вывод,и выйдите из (или продолжите работу в фазе -f).

Теперь позвольте мне напомнить вам, что конец -файла -на канале никогда не наступает до тех пор, пока не завершится восходящая программа1 ...

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

  • Но вы видите не весь вывод на данный момент, а скорее только последние 10 строк вывода на данный момент.

    Если вы попросили свой скрипт проанализировать 20 файлов (с менее чем 10 файлами за раз, см. следующий пункт ), вы получите только результат последних 10 файлов, проанализированных непосредственно перед тем, как вы убили скрипт первым. время. Это нарушает ожидания (, т. е. целостность )работы вашего скрипта , где результат каждого выполненного анализа должен был сообщаться на выходе.

  • Эта проблема также затрагивает tail -f input. Сброс списка файлов с более чем 11 именами файлов в ваш канал inputв первый раз приведет к тому, что только 10 самых нижних имен достигнут вашего скрипта, снова нарушив целостность работы вашего скрипта . Во второй и последующие разы это не будет проблемой.

И это еще не конец истории...

Достигнув первого конца -файла -, tail -fпродолжит работу в фазе -f, что означает, что выводит все, что впоследствии было добавлено во входной файл .

На этом этапе дескриптор ввода еще не закрыт; он зарегистрирует прослушивательinotifyво входном файле и будет ждать. Каждый раз, когда какая-либо программа записывает/закрывает входной файл,tailснова прочитает дескриптор ввода (и выведет все, что он только что прочитал ), пока не встретит конец -файла -2 , и он вернется чтобы снова ждать. Промойте и повторяйте, пока не завершите работу tail -fвручную.

  • Уловка здесь заключается в том, что " выводит все, что только что было прочитано " также подвергается обычной буферизации вывода , когда вывод не является терминальным.

    Это не влияет на использование вами tail -f outputкак такового (, так как его выходная ветвь является терминалом ). tail -f inputоднако будет затронут:

    • Если вы ввели несколько имен файлов в интерактивном режиме с помощью cat > input, вы увидите, что обработка не начнется, пока вы не завершите cat.
    • И это означает, что подключение inputканала к длинной -работающей программе, которая лишь изредка выдает имена файлов, также не будет работать.

Заключение

Насколько я понимаю, вы использовали tail -f input, чтобы защитить свой скрипт от получения конца -файла -, чтобы ваш скрипт мог продолжать работать как демон , в то время как имя файла -дает программы могут просто приходить и уходить.

Поэтому я советую вместо этого использовать tail -n +1 -f, чтобы убедиться, что tailне будет бесконечных поисков конца -файла -, и удалить последние -10 -линейная проблема. Затем используйте stdbufдля управления буферизацией, где это может вызвать проблемы 3,4 ...

stdbuf -oL tail -n +1 -f input |../entropyCalc/entropy.py > output 2>&1

Затем на стороне мониторинга используйте:

tail -n +1 -f output

или:

while true; do cat output; done

Сноски

  • 1 Или, точнее, когда вышестоящая программа закрывает канал. (В вашем случае это произойдет только tail -f output, когда ваш скрипт завершится)
  • 2 Никогда не случится с вашим tail -f output, если только вы не завершите свой скрипт в второй раз.
  • 3 Ваш скрипт уже является строкой -, буферизованной на выходном каскаде, поэтому здесь нет необходимости в stdbuf.
  • 4 Стандартное перенаправление ошибок 2>&1также обеспечивает отображение ошибки сценария на терминале мониторинга.
-1
28.01.2020, 05:04

Теги

Похожие вопросы