我正在尝试学习 Bash 脚本,为了好玩,我想编写一个脚本来监视httpd.service
.
基本构造如下所示:
#!/bin/bash
SERVICE=httpd.service
if [ "systemctl show -p ActiveState $SERVICE | sed 's/ActiveState=//g'" != "active" ] && [ "systemctl show -p SubState $SERVICE | sed 's/SubState=//g'" != "running" ]
then
echo "$SERVICE is inactive" | mailx -r [email protected] -s "$SERVICE not running on $HOSTNAME" [email protected]
fi
有用。是否以安全和最佳实践的方式编写,我想不是,但这是我的第二天,我首先需要了解一般脚本背后的想法。
如何获取test
变量中两个条件的结果,以便将状态和子状态打印到邮件中?我想我可以做这样的事情:
#!/bin/bash
SERVICE=httpd.service
STATE=$(systemctl show -p ActiveState $SERVICE | sed 's/ActiveState=//g')
SUBSTATE=$(systemctl show -p SubState $SERVICE | sed 's/SubState=//g')
if [ "$STATE" != "active" ] && [ "SUBSTATE" != "running" ]
then
echo "$SERVICE state is $STATE and substate is $SUBSTATE"
fi
但不确定这是否是一种优雅的方法?
编辑
感谢您提出的宝贵意见!我已经把他们全部投了!
所以,基本上我最终是通过以下方式完成的:
#!/bin/bash
SERVICE=httpd.service
HOST=$(grep '^ServerName' /etc/httpd/conf/httpd.conf | sed 's/^.* //')
[email protected]
if [ "$(systemctl show -p ActiveState $SERVICE | sed 's/ActiveState=//g')" = "active" ]
then
echo "$SERVICE is running" >/dev/null
else
systemctl restart $SERVICE 2>/dev/null
if [ "$(systemctl show -p ActiveState $SERVICE | sed 's/ActiveState=//g')" = "active" ]
then
echo "$SERVICE on $HOST has been started" | mailx -r "${HOST}"@blabla.com -s "$SERVICE on $HOST restarted" $EMAIL
else
echo "$SERVICE on $HOST is stopped and could not be started!" | mailx -r "${HOST}"@blabla.com -s "$SERVICE on $HOST has encountered a problem!" $EMAIL
fi
fi
您能看一下吗?是否有使用任何不符合 POSIX 标准的样式?
答案1
你的第一个脚本不起作用,你需要
if [ "$(cmd)" != "active" ]
代替
if [ "cmd" != "active" ]
第二个剧本看起来不错。
注意与 结合使用的否定条件&&
。它可能不会给出您想要的结果。我认为你想要||
而不是&&
.
您不需要此处的替换g
选项sed
,但这也没有什么坏处。
但如果你使用集成的函数,那就更优雅了systemctl
:
systemctl is-enabled httpd.service >/dev/null || echo "Service not enabled"
systemctl is-active httpd.service >/dev/null || echo "Service not active"
systemctl is-failed httpd.service >/dev/null && echo "Service is failed"
答案2
正如@RoVo 所说,请注意你的逻辑。你可能想要
if [[ ! ("$STATE" = "active" && "SUBSTATE" = "running") ]]
注意 bash 的使用[[ ... ]]
或更便携
case "$STATE,$SUBSTATE" in
"active,running") echo ok ;;
*) echo not ok ;;
esac