我有一个脚本可以测试服务器是否已启动并正在运行,如果向下写入日志文件中的多长时间 脚本工作正常,但我喜欢写更少的写作来加快速度 就像现在一样,它为每个测试的服务器编写完整的日志文件 可以将信息存储在某个变量或数组中,然后写入一次。
#!/bin/bash
STATUS="/usr/local/server.info"
LOG="/var/log/servers_up_log"
# What server to monitor
SRV=(SR1 SR2 SR3)
# Test if log file exists, if not create it.
if [[ ! -f "$LOG" ]]; then
>"$LOG"
fi
for UC in ${SRV[*]}; do
# Test if server is already in log, if not add it.
if ! grep -q $UC "$LOG" ; then
echo "$UC|0" >> "$LOG"
fi
isup=$(awk -F\| '$1==test {if ($2~/connected/) print "1"; else print "0"}' test="$UC" "$STATUS")
if [[ $isup = 1 ]]; then
#if server is up, add "0" to log file
awk -F\| '$1==test {$2=0}1' OFS=\| test="$UC" "$LOG" > tmp && mv tmp "$LOG"
else
#if server is down for first time update log file
if [[ $(awk -F\| '$1==test {print ($2==0?0:1)}' test="$UC" "$LOG") = 0 ]]; then
awk -F\| '$1==test {$2=date}1' OFS=\| test="$UC" date="$(date +"%Y/%m/%d %T")" "$LOG" > tmp && mv tmp "$LOG"
fi
fi
done
STATUS
是保存服务信息的文件
LOG
是写入状态的文件,它看起来像这样:
SR1|0
SR2|2014/05/12 20:25:05
SR3|0
如果其0
启动并运行。日期显示何时下降
SRV
数组不是这样的,它是从文件中读取的动态数量的服务器
我刚刚添加了三台服务器来查看该程序的样子。
所以程序就是这样的:
测试LOG
文件是否存在,如果不存在空文件。
然后为SRV
中的每个服务器:
查看它是否在LOG
文件中,如果没有,请添加0
,服务器向上。
然后在STATUS
文件中查看是否已连接
如果已连接,请将LOG
文件中的服务器标记设置为0
,
如果未连接,请将LOG
文件中服务器的标志设置为日期,
但仅限于之前的0
,以防止更新日期。
正如您在awk
部分中看到的那样:
$1==test {$2=0}1
它为每个服务器写入整个LOG
文件,因此对于许多服务器,它会多次写入LOG
文件。而且不仅每次运行一次脚本。
答案 0 :(得分:0)
使用use-array-variable-in-awk中的提示。我只显示了我修改过的脚本部分:
if [[ $isup = 1 ]]; then
#if server is up, add "0" to log file
#awk -F\| '$1==test {$2=0}1' OFS=\| test="$UC" "$LOG" > tmp && mv tmp "$LOG"
keys+=($UC); values+=(0) # storing the server name and the value to be stored in arrays
else
#if server is down for first time update log file
if [[ $(awk -F\| '$1==test {print ($2==0?0:1)}' test="$UC" "$LOG") = 0 ]]; then
#awk -F\| '$1==test {$2=date}1' OFS=\| test="$UC" date="$(date +"%Y/%m/%d %T")" "$LOG" > tmp && mv tmp "$LOG"
keys+=($UC); values+=(1)
fi
fi
然后在for循环之后添加这个awk命令:
awk -v ks="${keys[*]}" -v vs="${values[*]}" -v date="$(date +"%Y/%m/%d %T")" '
BEGIN{ split(ks, keys, / /); split(vs, values, / /);
FS="|"; OFS="|"; }
{
for (i in keys) {
if(keys[i] == $1) { $2 = values[i]; break; }
};
if ($2 == 1) { $2 = date }
}
1
' $LOG > tmp && mv tmp $LOG
因此,我们创建了两个数组keys
和values
。 keys
存储服务器名称,values
存储我们要针对这些服务器写入的值。在最后的awk命令中,我们从bash数组创建awk数组。有关解释,请参阅use-array-variable-in-awk。
这里的一个问题是values
不能有空格,我们的日期格式有一个空格。我使用了一个简单的“1”来表示该值必须是一个日期,然后用新的awk命令中的日期值替换。
awk中的for循环只是遍历keys
数组,如果此数组中的servername与$1
匹配,则它使用当前索引从values
中查找相应的值阵列。此外,如果值为“1”,我们使用日期值。
答案 1 :(得分:0)
我这样做:
awk -v date="$(date +"%Y/%m/%d %T")" -v srv="${SRV[@]}" '
BEGIN {
FS=OFS="|"
split(srv,srvArr,/ /)
}
NR==FNR {
for (i=1; i in srvArr; i++) {
if ($1 == srvArr[i]) {
prevStatus[i] = $2
}
}
next
}
{
for (i=1; i in srvArr; i++) {
if ($1 == srvArr[i]) {
currStatus[i] = $2
}
}
}
END {
for (i=1; i in srvArr; i++) {
# Test prev and curr status arrays and print
# whatever you need to for each combination.
prev = prevStatus[i]
curr = currStatus[i]
if (prev == "") {
if (curr == "") {
}
else if (curr == "connected") {
}
else {
}
}
else if (prev == "connected") {
etc...
}
}
}
' "$LOG" "$STATUS" > tmp && mv tmp "$LOG"
改变"已连接"如果/在适当的时候为1。必要时使用日期变量。如果你需要附加到日志文件而不是覆盖它,请附加tmp而不是mv-ing等等。