如果在 crontab 下运行,Bash 多 ping 脚本具有空变量

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

我拼凑了一个 bash 脚本来在 Centos/Debian 上进行多 ping 日志记录,当从控制台运行时它工作正常,但在 crontab 下运行时,变量 $NUM 留空。

它有 2 个组件,一个 cfg 文件:

### Main program variables:
SPOOLDIR="/var/spool/pingstats"
BADPINGSDIR="/tmp/badpings"
BADPINGLOG="$BADPINGSDIR/badpings.log"
PINGLOG="$PROGRAMDIR/ping.log"

##### Set NODE NAMES (its just a name), host can be IP or hostname ie abc.com and maxping latency thresholds (edit/add nodes as needed)
NODENAME01=router
HOST01=10.0.0.1
MAXPING01=5

NODENAME02=dns1
HOST02=68.6.16.30
MAXPING02=35

NODENAME03=dns2
HOST03=1.1.1.1
MAXPING03=35

NODENAME04=fibergw
HOST04=77.77.77.74
MAXPING04=10

## Several more....

剧本:

#!/bin/bash

## Base variables
PROGRAMDIR="/root/pingstats"
PINGCONF="$PROGRAMDIR/PingConfig.cfg"
TIMESTAMP="$(date +%Y%m%d%H%M)"
TIMESTAMP2() {
  date +"%Y-%m-%d_%H:%M:%S" # current time
}

source $PINGCONF

## check dir structure:
if [ ! -d $SPOOLDIR ]; then
        mkdir $SPOOLDIR
fi

## Loop through each nodename listed in cfg
for n in `grep [N]ODENAME $PINGCONF`
        do
        echo "Processing Node: $n"
        NODENAME=$(echo "$n" | awk -F'=' '{ print $2 }')
#### The next couple of lines are the problem, because $NUM ends up blank via cron
        NUM=$(grep -oE '[N]ODENAME.{,2}' <<< "$n" | grep -o '[0-9]\+')
        HOSTTMP=HOST$NUM
        HOSTIP=${!HOSTTMP}
        echo "NODE is $NODENAME and HOSTIP is $HOSTIP"
        if [ ! -d "$SPOOLDIR/$NODENAME" ]; then
                mkdir "$SPOOLDIR/$NODENAME"
        fi
        echo "$(TIMESTAMP2) : Pinging NODE: $NODENAME at $HOSTIP logging to file:
        $SPOOLDIR/$NODENAME/$TIMESTAMP" >> $PINGLOG

        echo " Starting ping to $HOSTIP"
        ping -i 2 -s 8000 -c 300 $HOSTIP > "$SPOOLDIR/$NODENAME/$TIMESTAMP" &

        sleep 1
done

预计会看到多个进程正在运行 ping。日志记录向我展示了这一点:

2024-09-05_01:06:03 : Pinging NODE: dns1 at  logging to file:
        /var/spool/pingstats/dns1/202409050106

at后面有一个空格,应该显示$NUM

bash loops cron
1个回答
0
投票

我将如何解析您的配置文件:

基于

### Main program variables:
SPOOLDIR="/var/spool/pingstats"
BADPINGSDIR="/tmp/badpings"
BADPINGLOG="$BADPINGSDIR/badpings.log"
PINGLOG="$PROGRAMDIR/ping.log"

##### Set NODE NAMES (its just a name), host can be IP or hostname ie abc.com and maxping latency thresholds (edit/add nodes as needed)
NODENAME01=router
HOST01=10.0.0.1
MAXPING01=5

NODENAME02=dns1
HOST02=68.6.16.30
MAXPING02=35
NODENAME03=dns2
HOST03=1.1.1.1
MAXPING03=35

NODENAME04=fibergw
HOST04=77.77.77.74
MAXPING04=10

## Several more....
#!/bin/bash

## Base variables
PROGRAMDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PINGCONF="$PROGRAMDIR/PingConfig.cfg"
printf -v TIMESTAMP '%(%Y%m%d%H%M)T' -1

TIMESTAMP2() {
    printf '%(%Y-%m-%d_%H:%M:%S)T\n' -1
}

declare -i cnt=0
crtNode=conf
declare -A "$crtNode=()"
while IFS== read -r fld val; do
    case ${fld//[ $'\t']} in
        '' )
            [[ -v $crtNode[NODENAME] ]] || [[ $crtNode = conf ]] || continue
            cnt+=1
            printf -v crtNode node_%02d $cnt
            declare -A "$crtNode=()"
            continue ;;
        \#*)
            continue ;;
    esac
    if [[ $crtNode = conf ]]; then
        val=${val//\"}
        val=${val/\$BADPINGSDIR/$BADPINGSDIR}
        val=${val/\$PROGRAMDIR/$PROGRAMDIR}
    fi
    printf -v $crtNode[${fld%?[0-9]}] %s "$val"
done < "$PINGCONF"
[[ -v $crtNode[NODENAME] ]] || unset $crtNode

declare -p conf ${!node_*}
© www.soinside.com 2019 - 2024. All rights reserved.