1

Я делаю довольно стандартный tail + grep:

tail -f some_log_file.txt | grep -q known-string

Если я запускаю команду без -q:

tail -f some_log_file.txt | grep known-string

Я вижу вывод:

[Tue Feb 12 11:32:45 2019] known-string.

так что я знаю, что grep совпадает. Однако, когда я добавляю -q команда grep не завершается, она просто зависает там, ожидая дополнительных выходных данных ... даже несмотря на то, что на странице руководства написано, что она "немедленно завершится с нулевым статусом, если найдено какое-либо совпадение":

   -q, --quiet, --silent
          Quiet;  do  not  write  anything  to  standard   output.    Exit
          immediately  with  zero status if any match is found, even if an
          error was detected.  Also see the -s or --no-messages option.

Может кто-нибудь объяснить, почему -q не вызывает моего grep для выхода? Я пытаюсь && beep до конца, чтобы grep звуковой сигнал, когда найдено совпадение, но если я не смогу выйти из него, это не сработает.

2 ответа2

3

Из сообщения StackOverflow «grep -q» не завершается с «tail -f»:

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


Решение вашей проблемы, вероятно, будет (не проверено и, скорее всего, будет плохо работать):

tail -f logfile | while read line; do
  echo $line | grep -q 'find me to quit' && break;
done

Вы найдете больше информации и решений в связанном посте.

2

grep действительно выходит, и труба уходит, хотя tail продолжает бежать. Этот журнал отчетов об ошибках начинается с варианта использования, очень похожего на ваш:

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

$ echo xxx > /tmp/blabla
$ tail -f /tmp/blabla |grep -m1 --line-buffered "xxx"
xxx

Теперь tail все еще пытается прочитать и выходит, только если я снова пишу в /tmp/blabla .

Это так и должно быть?

Объяснение там:

tail завершает работу в SIGPIPE, однако он получает только сигнал от write() , поэтому вам нужно получить больше данных в файле, прежде чем tail выйдет.

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

Затем пришло это желание:

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

И наконец:

Реализовано в:
https://git.sv.gnu.org/cgit/coreutils.git/commit/?id=v8.27-42-gce0415f

И действительно, когда я пытаюсь воспроизвести вашу проблему с tail из GNU coreutils 8.28, я не могу. Инструмент выходит немедленно.

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