테스트 결과를 변수로 가져오는 bash 스크립트

테스트 결과를 변수로 가져오는 bash 스크립트

저는 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

관련 정보