我想实时监控一个日志文件,并在日志中出现某些句子时执行一些命令。
我搜索了这个网站(以及许多其他网站),这些是我尝试过的:
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)
答案1
Archemar 在他的回答中为您的确切问题提供了正确的解决方案。
然而,很明显,您可能想要执行常规命令,就像在 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
$>
这在我的手机上有效,所以我怀疑它对你不起作用的原因可能与树莓派有关,对此我无能为力,抱歉