我是脚本世界的新手,目前正在使用脚本对我管理的 san 设备执行运行状况检查。
该脚本很简单,它将命令的输出从远程设备重定向到当前文件到本地主机。然后,我使用 diff 命令来比较当前文件和参考文件的输出,并获取有关差异的电子邮件警报。
然而,我目前面临的问题是,每次运行脚本时,脚本执行后我都会收到一封电子邮件,也就是说,即使比较没有差异,我也会从脚本执行中收到一封空白电子邮件。
由于这与执行自动健康检查有关,因此每天收到空白电子邮件将会很麻烦。有没有什么方法可以调整差异或添加更多代码,以确保当差异没有显示差异时,我不应该收到电子邮件,而只有在存在差异并显示差异时才收到电子邮件。
当前脚本
### saves output of command switchshow in a file on local host
ssh user@ip_of_switch switchshow > switchshow_results
### Compares current output to reference file and mails the difference
diff switchshow_reference switchshow_results \
| mail -s device_PORT_ERROR email_recipient
如果需要任何其他信息,请告诉我。
感谢您的帮助和详细解释 Slm :)
到目前为止,我已经使电子邮件部分正常工作(仅当与diff
命令存在差异时我才会收到电子邮件)。然而,我现在收到的电子邮件将其测试连接成一长串,这不利于查看,并且对于将要收到它的人来说不容易理解。
我当前的脚本粘贴在下面:
ssh test@ip_of_device switchshow > switchshow_results
variable=`diff switchshow_reference switchshow_results`
if [[ $variable -eq 0 ]]
then
echo $"nothing"
else
echo $variable | mail -s switch_HARDWARE_CHECK recipeint_email_address
fi
上述脚本的输出是空白的,当命令diff
没有发现任何差异时我没有收到任何电子邮件。但是,当diff
命令发现差异时,我会收到一封电子邮件,粘贴如下:
16c16 < 0 0 010000 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 0 0 010000 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public 26c26 < 10 10 010a00 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 10 10 010a00 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public 29c29 < 13 13 010d00 id N4 Online FC F-Port 50:06:01:67:3b:20:23:0a --- > 13 13 010d00 id N4 No_Light FC F-Port 50:06:01:67:3b:20:23:0a
理想情况下,这应该在电子邮件中看起来像这样。
16c16 < 0 0 010000 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 0 0 010000 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public
26c26 < 10 10 010a00 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 10 10 010a00 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public
29c29 < 13 13 010d00 id N4 Online FC F-Port 50:06:01:67:3b:20:23:0a --- > 13 13 010d00 id N4 No_Light FC F-Port 50:06:01:67:3b:20:23:0a
输出应在电子邮件中一次显示一行。有什么建议么?
答案1
问题是您用来执行的命令diff
。每次该命令运行其结果时,无论是否存在差异,都会触发该mail
命令。
例子
在这里,我们将使用 2 个echo
命令来模拟这 2 个文件,如下所示:
$ diff <(echo 1) <(echo 2)
1c1
< 1
---
> 2
这看起来没问题,但是当echo
命令相同时会发生什么?
$ diff <(echo 1) <(echo 1)
$
好吧,这似乎不是一个问题,不是吗?如果我们通过管道将命令的输出diff
传递给另一个echo
命令会怎样:
$ diff <(echo 1) <(echo 1) | echo "hi"
hi
即使从diff
管道传输到另一个命令的空输出也会触发该命令运行。
那么什么是正确的方法呢?
你真正想做的是两件事之一。要么检查命令的状态diff
,要么使用逻辑运算符,例如 and &&
(与)或运算符||
(或运算符)。
地位
大多数命令在执行时都会返回一个状态。通常用零或一来表示它们运行成功或失败。您可以通过分析Bash 中的diff
状态变量来查看状态。$?
diff
如果文件匹配则返回 0
$ diff <(echo 1) <(echo 1)
$ echo $?
0
diff
如果文件不匹配则返回 1
$ diff <(echo 1) <(echo 2)
1c1
< 1
---
> 2
$ echo $?
1
因此它本身似乎很有用,我们可以判断命令是否成功运行。但是我们没有办法对此采取行动。那么让我们看看逻辑运算符。
逻辑运算符
另一种方法是更改 2 个命令,这样如果第一个命令成功,则第二个命令将运行。相反,如果第一个命令失败,您可以使用替代运算符运行第二个命令。
例子
不同的语用
$ diff <(echo 1) <(echo 2) || echo "they're different"
1c1
< 1
---
> 2
they're different
相同的编译指示
$ diff <(echo 1) <(echo 1) && echo "they're the same"
they're the same
笔记:如果您使用此方法,请务必小心。结构类型存在一个问题,因为以上是真正的逻辑运算符,就像 if .. then .. else 一样。您可以在bashpitfalls 网站。
所以这似乎是一个有效的方法。但也许还有另一种方法。继续阅读。
如果那么否则
第三种方法是使用 if/then 块来运行程序mail
。 if/then 命令与我刚才提到的逻辑运算符有关,它们称为条件语句。
笔记:而且diff
它确实不是用于 if/then 语句的最佳工具。最好使用cmp
仅返回状态的命令,仅返回状态。所以我们现在也升级一下。
例子
相同的
$ cmp -s <(echo 1) <(echo 1)
$ echo $?
0
不同的
$ cmp -s <(echo 2) <(echo 1)
$ echo $?
1
将其扩展为 if/then 块将如下所示:
$ if cmp -s <(echo 2) <(echo 1);then echo "same"; else echo "different";fi
different
$ if cmp -s <(echo 1) <(echo 1);then echo "same"; else echo "different";fi
same
你的问题
然后你可以对原来的问题做这样的事情:
if cmp -s switchshow_reference switchshow_results; then
diff switchshow_reference switchshow_results \
| mail -s device_PORT_ERROR email_recipient
fi
更新#1
在查看更新后的脚本时,您需要进行以下修改:
ssh test@ip_of_device switchshow > switchshow_results
variable=$(diff switchshow_reference switchshow_results)
if [[ $variable -eq 0 ]]
then
echo $"nothing"
else
echo -n "$variable" | mail -s switch_HARDWARE_CHECK recipeint_email_address
fi
您遇到的输出显示为单行的问题是由于您使用了 ,echo
而没有告诉它扩展特殊字符,例如\n
.例如:
$ echo "oneline\ntwoline"
oneline\ntwoline
$ echo -e "oneline\ntwoline"
oneline
twoline
我所做的另一项修改是如何执行diff
.这并没有以不好的方式影响您的功能,但反引号 ( \
..` ) has been deprecated in favor of this notation,
$(...)` 。这些具有能够将命令嵌套在其他命令中的额外好处,例如:
$ myvar=$(echo "good + $(echo bye)")
$ echo $myvar
good + bye
答案2
我在这里做同样的事情,但我用 subversion 保存我的配置,所以我做一个 svn diff 而不是普通的 diff。我的代码是:
diff=$(svn di)
if [ -n "$diff" ]
then
svn di | mail -s subject recipient
fi