Подавить сообщения обрезанных файлов при использовании tail

11

Я использую файл журнала, tail -f messages.logи это часть вывода:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Fusce eget tellus sit amet odio porttitor rhoncus. 
Donec consequat diam sit amet tellus viverra pellentesque. 
tail: messages.log: file truncated
Suspendisse at risus id neque pharetra finibus in facilisis ipsum.

Он показывает, tail: messages.log: file truncatedкогда файл усекается автоматически, и это должно произойти, но я просто хочу tailпоказать мне вывод без этого усеченного сообщения.

Я пытался использовать, tail -f messages.log | grep -v truncatedно это все равно показывает мне сообщение.

Есть ли способ подавить это сообщение?

Bas Peeters
источник

Ответы:

15

Это сообщение выводится на stderr, как и все предупреждения и сообщения об ошибках.

Вы можете удалить все сообщения об ошибках:

tail -f file 2> /dev/null

Или отфильтровать только сообщения об ошибках, которые содержат truncate:

{ tail -f file 2>&1 >&3 3>&- | grep -v truncated >&2 3>&-;} 3>&1

Это означает, однако, что вы потеряете статус выхода tail. Несколько оболочек имеют pipefailопцию (включается с помощью set -o pipefail) для этого конвейера, чтобы сообщать о состоянии выхода, tailесли он выходит из строя. zshи bashможет также сообщать о состоянии отдельных компонентов конвейера в их $pipestatus/ $PIPESTATUSмассиве.

С помощью zshили bashвы можете использовать:

tail -f file 2> >(grep -v truncated >&2)

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

В zsh, вы можете обратиться к этому, написав это:

{ tail -f file; } 2> >(grep -v truncated >&2)

Это обсуждается в zshдокументации по адресу info zsh 'Process Substitution':

Есть дополнительная проблема с >(PROCESS); когда это присоединено к внешней команде, родительская оболочка не ждет завершения PROCESS и, следовательно, следующая сразу команда не может полагаться на завершение результатов. Проблема и решение те же, что описаны в разделе MULTIOS в примечании Redirection :: . Следовательно, в упрощенной версии примера выше:

paste <(cut -f1 FILE1) <(cut -f3 FILE2) > >(PROCESS)

(обратите внимание, что MULTIOS не задействованы), PROCESS будет выполняться асинхронно, если это касается родительской оболочки. Обходной путь:

{ paste <(cut -f1 FILE1) <(cut -f3 FILE2) } > >(PROCESS)

Дополнительные процессы здесь порождаются из родительской оболочки, которая будет ожидать их завершения.

Стефан Шазелас
источник
Есть ли причина, по которой вы предпочитаете подоболочку ( )над сложной командой { }?
Том Хейл,
@TomHale. Нет веских причин. Смотрите редактировать. Спасибо.
Стефан Шазелас
2

Если grepне избавиться от вывода, скорее всего, он печатается со стандартной ошибкой. Самый простой способ избавиться от этого - просто сбросить его:

tail -f messages.log 2>/dev/null
l0b0
источник
1
Делает трюк, но также подавляет другие сообщения.
Bas Peeters
Да, у @ StéphaneChazelas есть решение, которое является более сложным, но игнорирует только соответствующее сообщение.
10
1

Может быть, поможет, если можно исправить происхождение этой ошибки. Это произошло потому, что что-то записывается в файл с перезаписью ">", а не с добавлением ">>".

Б.Г. Бруно
источник