Grep не может вывести данные в канал?

Grep не может вывести данные в канал?

У меня проблемы с grep-фильтрацией вывода make. В частности,

make target 2>&1 | grep -E --color=never "^make.*"

работает как и ожидалось, но следующее не выведет ничего на консоль:

make target 2>&1 | grep -E --color=never "^make.*" | cat

Я что-то упускаю очевидное? Почему первая команда выводит, а вторая нет? Это связано с какой-то буферизацией ввода-вывода? Или я просто туплю?

[РЕДАКТИРОВАТЬ]: catэто просто минимальный тестовый пример для реальной команды, которую я хочу использовать.

[РЕДАКТИРОВАТЬ]:Похоже, это не проблема с grep, так как замена его нааккприводит к такому же поведению.

[РЕДАКТИРОВАТЬ]:Скрипт, для которого cat является заполнителем:

#!/bin/bash
cat - \
 | grep -E --color=never "^.*warning:.*|^.*error:.*|^make.*[Ee]rror.*|^make.*" \
 | hilite.sh -r "^.*warning:.*" -f yellow -B \
 | hilite.sh -r "^.*error:.*" -f red -B \
 | hilite.sh -r "^make.*[Ee]rror.*" -f red -B \
 | hilite.sh -r "^make.*" -f magenta

[РЕДАКТИРОВАТЬ]:Я думаю, что это проблема буферизации/IO. Я оставляю сборку запущенной на w/e и посмотрю, получит ли она в итоге вывод туда, куда нужно!

решение1

Вероятно, grepобнаруживается, что он не пишет в TTY, поэтому он буферизует больше вывода, а не работает в обычном режиме буферизации строк (т. е. вы видите каждую строку по мере ее нахождения). Такое поведение более эффективно, поскольку приводит к меньшему количеству write()системных вызовов, но если вы пользователь, ожидающий конвейерного вывода, то это может немного ввести в заблуждение.

Если вы используете GNU grep(а судя по вашему тегу linux, я предполагаю, что вы используете его), проверьте опцию --line-buffered, которая заставит grepработать в более привычном режиме буферизации строк. Это может технически снизить производительность grep(как отмечено на странице руководства), но поскольку вы смотрите на вывод живой сборки, я сомневаюсь, что это как-то скажется в этом отношении.

решение2

Не уверены, что должна делать ваша команда. Есть ли файлы, в имени которых есть make.*?

Попробуйте изменить catна xargs cat?

решение3

Вы можете попробовать поэкспериментировать unbuffer, например,

make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat

Связанный контент