Problema usando tail e awk para monitorar log e executar um comando

0

Eu quero monitorar um arquivo de log em tempo real e executar alguns comandos quando algumas frases aparecerem no log.

Eu pesquisei este site (e muitos outros sites) e é isso que eu tentei:

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

ou

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

Mas eles não funcionam. Sempre que eu executo esses comandos, ele começa a esperar, mas, embora eu tenha certeza de que o arquivo de log muda, ele não imprime echo hello; na verdade, não faz nada. Apenas esperando: D

Então, o que devo fazer!?

(Sistema: Raspberry Pi. OS: Raspbian)

    
por Omid1989 14.02.2017 / 12:36

2 respostas

1

Archemar tem a solução correta para sua pergunta exata em sua resposta.

No entanto, é claro que você provavelmente quer executar comandos regulares, como você faria no bash, já que você usou "echo hello".

Nesse caso, será muito mais fácil se você ficar no bash, e então você tiver todo o seu poder à sua disposição (ao invés de ter que aprender como fazer isso dentro do awk), eu acho que você vai achar isso muito mais flexível e fácil de trabalhar.

método bash, em um liner:

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

Você pode fazer algo assim:

#!/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)' &

Exemplo de texto da execução de um teste no meu telefone 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
$>

Isso funciona no meu telefone, então eu suspeito que a razão pela qual ele não está funcionando para você pode ser algo a ver com o pi da framboesa que eu não posso ajudar com desculpe

    
por 14.02.2017 / 13:05
0

Use print para imprimir instruções no awk. para saber mais, consulte esta solução .

Para corresponder a string player_new use:

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

Para monitorar continuamente:

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

Mais sobre aqui .

    
por 14.02.2017 / 12:49