2

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

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

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

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

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

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

[EDIT]: похоже, это не проблема для grep, так как замена его на ack приводит к тому же поведению.

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

#!/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

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

3 ответа3

5

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

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

1

Не уверен, что ваша команда должна делать, cat любые файлы, которые делают. * В их имени файла?

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

1

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .