У меня проблемы с 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