Ваша проблема, скорее всего, связана с буферизацией в вашей системе, а не с чем-то, что не соответствует вашей строке кода. Мне удалось создать тестовый сценарий, где я мог бы воспроизвести его, а затем заставить его уйти. Надеюсь, это сработает и для вас.
Вот мой тестовый сценарий. Во-первых, я пишу короткий скрипт, который записывает время в файл каждые 100 мс (приблизительно) - это мой «лог-файл», который генерирует достаточное количество данных, которые uniq -c
должны дать мне интересный выход каждую секунду:
#!/bin/ksh
while :
do
echo The time is `date` >> a.txt
sleep 0.1
done
(Примечание - я должен был использовать ksh
, который имеет возможность сделать суб-второй sleep
)
в другом окне, я типа достаточно
tail -f a.txt | uniq -c
Конечно, вы получите следующий результат, появляющийся каждый второй:
9 The time is Thu Dec 12 21:01:05 EST 2013
10 The time is Thu Dec 12 21:01:06 EST 2013
10 The time is Thu Dec 12 21:01:07 EST 2013
9 The time is Thu Dec 12 21:01:08 EST 2013
10 The time is Thu Dec 12 21:01:09 EST 2013
9 The time is Thu Dec 12 21:01:10 EST 2013
10 The time is Thu Dec 12 21:01:11 EST 2013
10 The time is Thu Dec 12 21:01:12 EST 2013
и т.д. Никаких задержек. Важно отметить - Я не пытался вырезать время. Затем я сделал
tail -f a.txt | cut -f7 -d' ' | uniq -c
И ваша проблема воспроизводится - это будет «висеть» на некоторое время (пока не было 4k символов в буфере, а затем он будет рвать все это сразу).
Немного поиска в Интернете (https://stackoverflow.com/a/16823549/1967396) рассказал мне об утилите под названием stdbuf.В этой ссылке, в нем конкретно упоминается почти точно ваш сценарий, и они обеспечивают следующее временное решение (перефразируя, чтобы соответствовать моему сценарию выше):
tail -f a.txt | stdbuf -oL cut -f7 -d' ' | uniq -c
И это было бы здорово ... за исключением того, что эта утилита не существует на мой machine (Mac OS) - он специфичен для GNU coreutils. Это оставило меня неспособным проверить - хотя это может быть хорошим решением для вас.
Никогда не бойтесь - я нашел следующее обходное решение, основанное на команде socat
(о которой я, честно говоря, почти не понимаю, но я адаптировался из ответа, приведенного в https://unix.stackexchange.com/a/25377).
Сделайте небольшой файл с именем tailcut.sh
(это "long_running_command" из приведенной выше ссылке):
#!/bin/ksh
tail -f a.txt | cut -f7 -d' '
Дайте ему разрешение на выполнение с chmod 755 tailcut.sh
. Затем введите следующую команду:
socat EXEC:./tailcut.sh,pty,ctty STDIO | uniq -c
И эй престо - ваш кусковой выход больше комковатый. socat
посылает выходные данные из сценария прямо на следующий канал, и uniq
может сделать свое дело.
Вы бы писать свой собственный цикл (Баш скрипт), который обрабатывает вывод 'tail' и не обновляет счетчик до дата- изменения времени, затем распечатывает счетчик и сбрасывает счетчик? – Floris
@Floris, и это поможет? – yaccz
Собственно, какой формат даты, который входит в uniq? – yaccz