Проблема с использованием tail и awk для отслеживания журнала и выполнения команды

Я хочу отслеживать файл журнала в реальном времени и выполнять некоторые команды, когда появляются некоторые предложения в журнале.

Я искал этот сайт (и многие другие), и вот что я пробовал:

tail -f /var/log/omxlog | awk '/player_new/ { "echo hello" }'

или

stdbuf -o0 tail -F /var/log/omxlog | awk '/player_new/ { "echo hello" }'

Но они не работают. Всякий раз, когда я запускаю эти команды, он начинает ждать, но, хотя я уверен, что файл журнала изменяется, он не выводит echo hello; на самом деле это ничего не делает. Просто жду: D

Итак, что мне делать!?

(Система: Raspberry Pi. ОС: Raspbian)

0
14.02.2017, 13:36
2 ответа

В своем ответе Архемар найдет правильное решение для вашего точного вопроса.

Однако ясно, что вы, вероятно, захотите выполнять обычные команды, как в bash, поскольку вы использовали "echo hello".

В этом случае будет намного проще, если вы останетесь в bash, и тогда в вашем распоряжении будет вся его мощь (вместо того, чтобы учиться делать это в awk), я думаю, вы найдете гораздо больше гибкий и простой в работе.

метод bash в одной строке:

tail .... | while read ; do [[ "{REPLY}" =~ player_new ]] && echo hello ; done

Вы можете сделать что-то вроде этого:

#!/bin/bash

tail_log()
{
    tail -f "${1}"
    # or use stdbuf here instead
}

do_player_new()
{
  local log_line="${1}"
  echo "hello"
}

do_something_else()
{
  local log_line="${1}"
  echo "example: line was ${1}"
}

process_match()
{
  local full_line="${1}"

  case "${BASH_REMATCH[1]}"  #this bash_rematch array holds the part of the line that matched the () in the pattern 
  in
    player_new)      do_player_new "${full_line}";;
    something_else)  do_something_else "${full_line}";;
    another_example) do_another_example "${full_line}";;
  esac

  #or you could actually just execute this:
  # "do_${BASH_REMATCH[1]}" "${full_line}"
}

process_log()
{
  local logfile="${1}"
  local matcher="${2}"

  tail_log "${logfile}" | while read line
  do 
    # this checks the line against the regular expression
    # and the result of the match (parts between ()) will
    # be stored in the BASH_REMATCH array
    [[ "${line}" =~ ${matcher} ]] && process_match "${line}"
  done
}

process_log /var/log/omxlog '(player_new|something_else)' &

process_log /some/other/log '(another_example)' &

Пример текста из запуска теста на моем телефоне Android

$> while sleep 5 ; do echo player_new >> test.txt ; done &
[2] 3110
$> tail -f test.txt | while read ; do [[ "${REPLY}" =~ player_new ]] && echo $(date) hello; done
Wed Feb 15 01:39:12 ACDT 2017 hello
Wed Feb 15 01:39:12 ACDT 2017 hello
Wed Feb 15 01:39:12 ACDT 2017 hello
Wed Feb 15 01:39:15 ACDT 2017 hello
Wed Feb 15 01:39:20 ACDT 2017 hello
^C
$>

Это работает на моем телефоне, поэтому я подозреваю, что причина в другом. работа на вас может быть связана с raspberry pi, с которой я не могу помочь, извините

1
28.01.2020, 02:46

Используйте print для печати утверждений в awk. для получения дополнительной информации обратитесь к этому решению.

Для поиска строки player_new используйте :

awk '$1 ~ /player_new/ {print $1}' /var/log/omxlog

Для постоянного мониторинга :

tail -f /var/log/omxlog | awk '$1 ~ /player_new/ {print $1}'

Подробнее об этом здесь.

0
28.01.2020, 02:46

Теги

Похожие вопросы