bash - 获取最后日志 10 分钟的 shell 脚本问题
问题描述
我写了一个脚本来检查最后 10 分钟的最后一个 httpd 错误日志,但是我得到一个错误,它一直在循环:问题是脚本的输出是一个错误循环,直到日志文件结束我才得到日期 -通过运行 cmd date --date='-10min' 10 分钟,然后我逐行解析日志文件,然后检查日志文件中每一行的小时和分钟是否大于或等于日期的小时和分钟 -这里的 10 分钟是输出的一部分:
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
当我尝试在这里调试它时,这是问题的一部分,并且它在日志文件的每一行中重复:
+ IFS=
+ read -r line
+ errorBool=0
+ [[ [Sun Apr 28 03:52:39.791442 2019] [autoindex:error] [pid 15012]
[client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/:
No matching DirectoryIndex (index.html,index.php) found, and server-
generated directory index forbidden by Options directive == *:error* ]]
++ awk -F : '{printf $1}'
++ '[Sun' Apr 28 03:52:39.791442 '2019]' '[autoindex:error]' '[pid'
'15012]' '[client' '127.0.0.1:49054]' AH01276: Cannot serve directory
/var/www/html/: No matching DirectoryIndex '(index.html,index.php)' found,
and server-generated directory index forbidden by Options directive
test2.sh: line 26: [Sun: command not found
++ awk '{printf $4}'
+ '[' -ge 12 ']'
test2.sh: line 26: [: -ge: unary operator expected
这是代码:
#!/bin/bash
#SCRIPT TO CHECK THE ERROR LOGS IN THE LAST 10 MINS
#VARIABLES
#NUMBER OF ERROR LOGS
errorCount=0
DATE_10_MIN=$(date --date='-10min' | awk '{print $4}' )
DATE_10_MIN_HOURS=$(date --date='-10min' | awk '{print $4}' | awk -F :
'{print $1} ')
DATE_10_MIN_MIN=$(date --date='-10min' | awk '{print $4}' | awk -F :
'{print $2} ')
#_______________________#
while IFS= read -r line ; do
#BOOLEAN TO CHECK IF THE LINE HAVE THE EXPRESSION
errorBool=0
#if [[ $($line | awk '{print $4 }' | cut -c-8) -gt $DATE_10_MIN ]] ;
then
if [[ $line == *:error* ]] ; then
if [ [ $($line | awk '{print $4}' | awk -F : '{print $1}' )
-ge $DATE_10_MIN_HOURS ] && [ $($line | awk '{print $4}' | awk -F :
'{print $2}') -ge $DATE_10_MIN_MIN ] ]; then
errorBool=1
(( errorCount++ ))
echo $line
fi
fi
done < /var/log/httpd/error_log
echo "There were $errorCount error logs in the last 10 mins "
解决方案
这适用于我的测试系统。要正确测试它,您必须更改输入数据中的日期:)。
代码
#!/bin/bash
#Script to check the error logs in the last 10 mins
#Variables. Note: user variables should not be all uppercase.
errorCount=0
# Number of error logs found
date_10_min_ago="$(date --date='-10min' +'%s')"
# Time in seconds so it can be compared.
# See https://unix.stackexchange.com/a/170982/63804 .
#_______________________#
while IFS= read -r line ; do
if [[ $line == *:error* ]] ; then
line_timestamp="$(awk -F '[][]' '{print $2}' <<<"$line")"
# Get the date string, which is between brackets
record_time="$(date --date="$line_timestamp" +'%s')"
# Convert the date string to seconds.
# Thanks to https://stackoverflow.com/a/1842754/2877364
if (( record_time > date_10_min_ago)) ; then
(( ++errorCount ))
echo $line
fi
fi
done < 178.txt
echo "There were $errorCount error logs in the last 10 mins "
# vi: set ts=4 sts=4 sw=4 et ai:
样本输入
[Mon May 6 07:35:39.791442 2019] [autoindex:error] [pid 15012] [client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.php) found, and server-generated directory index forbidden by Options directive - this error is older than 10 min
[Mon May 6 08:35:39.791442 2019] [autoindex:error] [pid 15012] [client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.php) found, and server-generated directory index forbidden by Options directive
[Mon May 6 08:35:40.123456 2019] [autoindex:success] [pid 15012] [client 127.0.0.1:1337] Example input that doesn't contain the word "e r r o r"
输出
[Mon May 6 08:35:39.791442 2019] [autoindex:error] [pid 15012] [client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.php) found, and server-generated directory index forbidden by Options directive
There were 1 error logs in the last 10 mins
解释
- 如果日期是数字,比较日期会容易得多。该
date +'%s'
格式给出了每个日期的秒数*。 - 您可以从带有
awk -F '[][]'
. The[][]
是匹配 a[
或 a的正则表达式]
。因此,awk -F '[][]' '{print $2}'
获取错误日志的时间戳文本。然后date
用于将该日期文本转换为秒数以进行比较。 - 一般评论:我更喜欢把我的所有东西都包装起来
$()
,就"$()"
好像我想要所有的输出一样。我认为这更清楚。 正如@lojza 也提到的,一般来说,任何 bash 命令都必须完全在一行上。所以
DATE_10_MIN_HOURS=$(some random code)
很好,但是DATE_10_MIN_HOURS=$(some random code and more code on a different line)
会导致错误。
* 这可能无法在闰秒内按原样工作。
推荐阅读
- c++ - 在控制台应用程序中运行外部文本编辑器 - C++
- php - 如何在 Laravel 中为多模型路由命名策略?
- c# - Umbraco 检查 - 使用模糊和通配符搜索
- python - RandomizedSearchCV 最优组合
- php - PHP - 我的用于获取文件名和查找新文件的脚本可以更快吗?
- r - For循环合并df
- r - 如何使用 search.prime()、循环和 cat 在 R 中找到小于 100 的孪生素数
- redirect - Netlify 功能 - 仅用于 facebook 推荐的重定向
- c# - 在 C# 中传递一个布尔值
- apache-flink - JobListener 是否会为 JobStatus 中的*每一次*更改而调用?