4

Я пытаюсь сделать следующее в скрипте Bash: выполнить команду (например, tail -f log_file), дождаться получения определенного вывода, затем остановить команду и продолжить работу со скриптом.

Я попробовал следующее, но это не сработало:

tail -f log_file | grep some_text | head -n1

У меня нет выхода таким образом.

Теперь я попытался диагностировать проблему. Когда я просто запускаю tail -n1 , затем набираю что-то в терминале, оно выходит после первой строки. Однако, если я запускаю следующее:

grep some_text | head -n1

В этом случае я не получаю вывод до тех пор, пока не нажму CTRL+D, а затем он напечатает первую строку ввода, содержащую some_text .

Мой вопрос, почему это? Если head выдает первую строку сразу в первом случае, почему не получается, когда она получает данные из канала? Разве он не должен выводить все для первых n строк, а затем выходить, посылая сигнал SIGPIPE на другой конец канала?

2 ответа2

2

grep буферизует ваш ввод. Попробуйте grep --line-buffered .

Есть дополнительная проблема, head прекратит работу только после того, как получит вторую строку, что может быть проблемой, если ваш лог-файл низкочастотный. См. Как прочитать одну строку из tail -f через конвейер, а затем завершить? ,

0

Когда вы запускаете tail -n1 без ввода, он завершает работу после первой строки ввода из STDIN, как это должно работать. Когда вы запускаете grep some_text | head -n1 вы опять не вводите какие-либо входные данные для grep , поэтому кажется, что поведение, которое вы описываете, является нормальным. Когда вы нажимаете CTRL D, вы закрываете канал STDIN, и head -n1 что `grep получил от STDIN.

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