bash script obtém resultado do teste em variável

1

Estou tentando aprender scripts Bash e, por diversão, gostaria de escrever um script que monitore o httpd.service .

A construção básica é assim:

#!/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

funciona. Se está escrito de uma forma segura e melhor prática, eu acho que não, mas é o meu segundo dia e eu primeiro preciso ter uma idéia por trás de scripts em geral.

Como posso obter o resultado das duas condições test em uma variável para que eu possa imprimir o status e substatus no e-mail? Eu acho que poderia fazer algo como:

#!/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

Mas não tenho certeza se essa é uma maneira elegante de fazer isso?

EDITAR

Obrigado por todos os seus comentários valiosos! Eu votei todos eles!

Então, basicamente acabei fazendo da seguinte maneira:

#!/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

Poderia, por favor, dar uma olhada nisso? Existe algum estilo, não compatível com POSIX?

    
por blablatrace 05.09.2018 / 11:16

2 respostas

2

Seu primeiro roteiro não funciona, você precisa

if [ "$(cmd)" != "active" ]

em vez de

if [ "cmd" != "active" ]

O segundo script parece bom.
Tome cuidado com as condições negadas combinadas com && . Pode não dar o resultado que você está procurando. Eu acho que você quer || em vez de && .

Você não precisa da opção g para sed de substituição aqui, mas também não faz mal.

Mas seria mais elegante se você usasse as funções systemctl integradas:

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"
    
por 05.09.2018 / 11:28
1

Como o @RoVo diz, tenha cuidado com sua lógica. Você provavelmente quer

if [[ ! ("$STATE" = "active" && "SUBSTATE" = "running") ]]

observe o uso do bash [[ ... ]]

ou mais portavelmente

case "$STATE,$SUBSTATE" in
    "active,running") echo ok ;;
                   *) echo not ok ;;
esac
    
por 05.09.2018 / 22:18