Bash 脚本 - If Else 语句计算结果为 TRUE

问题描述 投票:0回答:1

我想就我编写的脚本遇到的这个特殊问题寻求您的建议。

它具有单模式(检查 1 个服务器)或多模式(您可以将其指向每行包含多行主机名和 IP 地址的文本文件)。

对于每组主机名和 IP 地址,

  • 它将 ping IP 地址,(ping -c 4 )
  • 运行 nmap {sudo nmap -Pn -p )
  • 使用 check_nrpe 插件检查是否安装了 nagios 代理。

原始版本运行得非常好。但是,对于特定服务器,它会将运行 nmap 的函数的 IF 和 ELSE 条件评估为 true。

下面我提供了脚本以及 bash -x 的输出,其中 p 地址已被编辑。我已将令我困惑的输出加粗。

#!/usr/bin/env bash

Usage () {

echo -e "Usage Info"

}


while getopts ":H:S:T:f:p:PMN" opt;
do
    case $opt in
        H)  # Host IP Address. Use this option if checking only single host. 
            HostAddr=$OPTARG
            RunMode=1
            ;;

        S)  # Host Name. Use this option if checking only single host. 
            HostName=$OPTARG
            ;; 

        f)  # absolute path to the text file containing list of IP Addresses. Use this option if checking multiple hosts. 
            HostFile=$OPTARG
            RunMode=2 
            ;;

        P)  # Ping the hostnames.   
            PingOn=1 
            ;;

        M)  # Check using NMAP if specified port is open. 
            CheckPort=1
            ;;

        p)  # Specify port to be used by NMAP. 
            NPort=$OPTARG
            ;;

        N)  # Check if NRPE agent is installed and configured.
            CheckNRPEOn=1
            ;;

        ?)  # Error in option. Shows Usage guide. 
            Usage
            ;;
    esac
done


cmd_Ping () {
    PingResult=$(ping -c 4 "$HostIP" | grep 'transmitted' | awk -F ' ' '{ print $4 }')
    if [[ "$PingResult" -eq 4 ]]; then
        PingStatus='OK'
    else
        PingStatus='FAILED'
    fi

    PingOut=$(echo -e "Ping: $PingStatus")
}


cmd_NMAP () {
    PortStatus=$(sudo nmap -Pn -p "$NPort" "$HostIP" | grep "$NPort" | awk -F ' ' '{ print $2 }')
            
    if [[ "$PortStatus" = 'open' ]]; then
        PortOut=$(echo -e "Port $NPort: OPEN")

    elif [[ "$PortStatus" = 'filtered' ]]; then 
        PortOut=$(echo -e "Port $NPort: FILTERED")

    elif [[ "$PortStatus" = 'closed' ]]; then 
        PortOut=$(echo -e "Port $NPort: CLOSED")    
    
    else
        PortOut=$(echo -e "Port $NPort: ERROR")
    fi
}


cmd_TNET () {
    PortStatus=$(echo -e '\x1dclose\x0d' | timeout 5 sudo telnet "$HostIP" "$NPort" | grep Connected | awk -F' ' '{ print $1}')
    
    if [[ "$PortStatus" = 'Connected' ]]; then 
        PortOut=$(echo -e "Port $NPort: OPEN")
    else 
        PortOut=$(echo -e "Port $NPort: FAILED")
    fi
}


cmd_NRPE () {
    NRPEtmp=$(sudo /usr/local/nagios/libexec/check_nrpe -H "$HostIP")
    NRPEnix=$(echo "$NRPEtmp" | awk -F ' ' '{ print $1 }')
    NRPEwin=$(echo "$NRPEtmp" | cut -d ' ' -f4-)
    if [[ "$NRPEnix" = 'NRPE' ]] || [[ "$NRPEwin" = 'seem to be doing fine...' ]]; then
        NRPEOut=$(echo -e "NRPE: Configured")
    else
        NRPEOut=$(echo -e "NPRE: Not Configured")
    fi
}


mode_Multi () {    # Multiple IP Address Mode 

    while read -r HostInfo;
    do
        HostName=$(echo "$HostInfo" | awk -F ' ' '{ print $1 }')
        HostIP=$(echo "$HostInfo" | awk -F ' ' '{ print $2 }')
        if [[ $PingOn -eq 1 ]]; then
            cmd_Ping
        else   # ($PingOn -ne 1 )
            PingOut='N/A'
        fi 

        if [[ "$CheckPort" -eq 1 ]]; then
            cmd_NMAP
        else   # ($CheckPort -ne 1)
            PortOut='N/A' 
        fi

        if [[ "$CheckNRPEOn" -eq 1 ]]; then
            cmd_NRPE
            NRPEOut='N/A'
        fi


        echo -e " $HostName, $HostIP, $PingOut, $PortOut, $NRPEOut"  
    done < "$HostFile"
}



mode_Single () {    # Single IP Address Mode 

    HostIP=$HostAddr

    if [[ $PingOn -eq 1 ]]; then
        cmd_Ping
    else   # ($PingOn -ne 1) 
        PingOut='N/A'
    fi 

    if [[ "$CheckPort" -eq 1 ]]; then
        cmd_NMAP
    else   # ($CheckPort -ne 1)
        PortOut='N/A' 
    fi

    if [[ "$CheckPort2" -eq 1 ]]; then 
        cmd_TNET
    else 
        PortOut='N/A'
    fi 

    if [[ "$CheckNRPEOn" -eq 1 ]]; then
        cmd_NRPE
    else  
        NRPEOut='N/A'
    fi

    echo -e "$HostName, $HostIP, $PingOut, $PortOut, $NRPEOut"      
}


if [[ "$RunMode" -eq 1 ]]; then 
    mode_Single 
else 
    mode_Multi
fi

这是单模式的输出:

我会像这样运行这个脚本:

./HostChecker.sh -S <HostName> -H <HostIP> -PMN -p <port number>

+ getopts :H:S:T:f:p:PMN opt
+ case $opt in
+ HostAddr=10.119.4.106
+ RunMode=1
+ getopts :H:S:T:f:p:PMN opt
+ case $opt in
+ PingOn=1
+ getopts :H:S:T:f:p:PMN opt
+ case $opt in
+ CheckNRPEOn=1
+ getopts :H:S:T:f:p:PMN opt
+ case $opt in
+ CheckPort=1
+ getopts :H:S:T:f:p:PMN opt
+ case $opt in
+ NPort=5666
+ getopts :H:S:T:f:p:PMN opt
+ [[ 1 -eq 1 ]]
+ mode_Single
+ HostIP=10.x.x.x 
+ [[ 1 -eq 1 ]]
+ cmd_Ping
++ ping -c 4 10.x.x.x 
++ grep transmitted
++ awk -F ' ' '{ print $4 }'
+ PingResult=0
+ [[ 0 -eq 4 ]]
+ PingStatus=FAILED
++ echo -e 'Ping: FAILED'
+ PingOut='Ping: FAILED'
+ [[ 1 -eq 1 ]]
+ cmd_NMAP
++ sudo nmap -Pn -p 5666 10.119.4.106
++ grep 5666
++ awk -F ' ' '{ print $2 }'
+ PortStatus=filtered
+ [[ filtered = \o\p\e\n ]]
+ [[ filtered = \f\i\l\t\e\r\e\d ]]
++ echo -e 'Port 5666: FILTERED'
+ PortOut='Port 5666: FILTERED'
+ [[ '' -eq 1 ]]
+ PortOut=N/A
+ [[ 1 -eq 1 ]]
+ cmd_NRPE
++ sudo /usr/local/nagios/libexec/check_nrpe -H 10.x.x.x 
+ NRPEtmp='CHECK_NRPE STATE CRITICAL: Socket timeout after 10 seconds.'
++ echo 'CHECK_NRPE STATE CRITICAL: Socket timeout after 10 seconds.'
++ awk -F ' ' '{ print $1 }'
+ NRPEnix=CHECK_NRPE
++ echo 'CHECK_NRPE STATE CRITICAL: Socket timeout after 10 seconds.'
++ cut -d ' ' -f4-
+ NRPEwin='Socket timeout after 10 seconds.'
+ [[ CHECK_NRPE = \N\R\P\E ]]
+ [[ Socket timeout after 10 seconds. = \s\e\e\m\ \t\o\ \b\e\ \d\o\i\n\g\ \f\i\n\e\.\.\. ]]
++ echo -e 'NPRE: Not Configured'
+ NRPEOut='NPRE: Not Configured'
+ echo -e ', 10.x.x.x , Ping: FAILED, N/A, NPRE: Not Configured'
, 10.x.x.x , Ping: FAILED, N/A, NPRE: Not Configured

如果查看 bash -x 的输出,您会注意到函数 cmd_NMAP 以某种方式将 IF 和 ELSE 的条件评估为 true。让我困惑的是那个条件“[[''-eq 1]]”我不知道它来自哪里。

我有一种感觉,这是一些简单的事情,我不知何故忽略了,但我已经花了几个小时了,但不知何故我看不到它。我什至使用 ShellCheck 检查过,它告诉我一切都很好。

非常感谢所有帮助。预先感谢您。

linux bash scripting nmap nrpe
1个回答
0
投票

我怀疑你的逻辑有问题,让我们看看:

    if [[ "$CheckPort" -eq 1 ]]; then
        cmd_NMAP
    else   # ($CheckPort -ne 1)
        PortOut='N/A' 
    fi

    if [[ "$CheckPort2" -eq 1 ]]; then 
        cmd_TNET
    else 
        PortOut='N/A'
    fi 

如果

CheckPort
1
,但
ChecPort2
不是
1
,会发生什么?

第一个

if
语句将执行
cmd_NMAP
,这将设置
PortOut
。但紧接着,下一个
if
语句将执行其
else
并破坏
PortOut

如果您希望所有这些情况都是排他性的,请采用另一种方式。也许你想要这个?

    if [[ "$CheckPort" -eq 1 ]]; then
        cmd_NMAP
    elif [[ "$CheckPort2" -eq 1 ]]; then 
        cmd_TNET
    else 
        PortOut='N/A'
    fi

仅当所有

CheckPort*
变量都不为 true 时,我们才会将
PortOut
设置为
N/A

© www.soinside.com 2019 - 2024. All rights reserved.