簡體   English   中英

Bash Shell 使用 IP 監控文件的腳本

[英]Bash Shell Script to monitor a file with IPs

我正在尋找一個腳本,我可以在 Up 或 Down 時使用 ping 命令監控 IP 文件。

我在 stackoverflow 上找到了兩種出色的方法,我正在嘗試將它們結合起來,但無論我做什么都行不通。 我正在閱讀 man shell 以了解未來,但我認為我遺漏了一些東西並且無法讓它發揮作用。

腳本 1:

我似乎找不到在 stackoverflow 上找到的腳本,但在此資源下找到了相同的腳本:(Bash 和 Ping)部分: https://jmanteau.fr/posts/the-facets-of-ping/#check-if-許多主機還活着

這個驚人的腳本可以非常快地並行 ping 多個主機

#!/bin/bash

argc=$#
if [ $# -lt 1 ]
then
   echo "Usage: $0 <ip-list-file>"
   exit 1
fi

hosts=$1

function customping 
{
    DATE=$(date '+%d/%m/%Y %H:%M:%S')
    ping -c 1 -W 1 $1 >/dev/null 2>&1 && echo "$DATE Node $1 is UP" || echo -e "\033[1;31m $DATE Node $1 is DOWN \033[0m"
# ping -c 1 -W 1 $1 >/dev/null 2>&1 && echo "$DATE Node $1 is UP" || echo "$DATE Node $1 is DOWN"
# sleep 0.01s
}

T="$(date +%s%N)"

DEFAULT_NO_OF_PROC=8
noofproc=$DEFAULT_NO_OF_PROC

if [ -n "$2" ] #user-set no. of process instead of default
then
  noofproc=$2
  echo "Max processes: $noofproc"
fi

export -f customping && cat $hosts | xargs -n 1 -P $noofproc -I{} bash -c 'customping {}' \;

腳本 2:

https://stackoverflow.com/a/4708831/19313640

這個驚人的腳本循環通過 IP 並顯示是向下還是向上(監控)

function check_health {

set 192.168.10.1 192.168.10.2 192.168.10.3 192.168.10.4 192.168.10.5 192.168.10.6 192.168.10.7 192.168.10.8 192.168.10.9 192.168.10.10 192.168.10.11 192.168.10.12 192.168.10.13

trap exit 2

for ipnumber in "$@"; do
  DATE=$(date '+%d/%m/%Y %H:%M:%S')
  ping -c 1 -t 1 $ipnumber > /dev/null
  [ $? -eq 0 ] && echo -e "|\033[1;36m $DATE \033[0m" "|\033[1;32m Node |"$ipnumber "| UP \033[0m" | column -t -s "|"
done

while true; do
  i=1
  for ipnumber in "$@"; do
    statusname=up$i
    laststatus=${!statusname:-0}
    ping -c 1 -t 1 $ipnumber > /dev/null
    ok=$?
    eval $statusname=$ok
    if [ ${!statusname} -ne $laststatus ]; then
      # echo $DATE Status changed for $ipnumber
      DATE=$(date '+%d/%m/%Y %H:%M:%S')
      if [ $ok -eq 0 ]; then
        echo -e "|\033[1;36m $DATE \033[0m" "|\033[1;32m Node |"$ipnumber "| UP \033[0m" | column -t -s "|"
      else
        echo -e "|\033[1;36m $DATE \033[0m" "|\033[1;31m Node |"$ipnumber "| DOWN \033[0m" | column -t -s "|"
      fi
    fi
    i=$(($i + 1))
  done
 # sleep 1
done

}

所以我的問題是如何將這兩個腳本放在一起,並使其與第一個腳本完全並行,並通過讀取文件而不是第二個腳本中的“設置”,以及第二個腳本的監視器功能。

編輯:如果至少使這項工作很復雜,我怎樣才能讓第二個腳本像第一個腳本一樣讀取文件作為參數?

我希望我是徹底的,並就我正在嘗試做的事情提供足夠的信息。

謝謝你。


更新:

你好,我已經設法讓它在一個混亂的代碼中工作。

#!/bin/bash

trap exit 2

argc=$#
if [ $# -lt 1 ]
then
   echo "Usage: $0 <ip-list-file>"
   exit 1
fi

hosts=$1


function check_live {

  trap exit 2

  DATE=$(date '+%d/%m/%Y %H:%M:%S')
    ping -c 1 -t 1 $1 > /dev/null
    [ $? -eq 0 ] && echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;32m Node |"$1 "| UP \033[0m" | column -t -s "|"
    # sleep 1
}

function check_health {

  trap exit 2

#  DATE=$(date '+%d/%m/%Y %H:%M:%S')
#    ping -c 1 -t 1 $1 > /dev/null
#    [ $? -eq 0 ] && echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;32m Node |"$1 "| UP \033[0m" | column -t -s "|"
#    sleep 3

  while true; do
  # while read line; do 
  # i="$i $line"
    i=1
    for ipnumber in "$@"; do
      statusname=up$i
      laststatus=${!statusname:-0}
      ping -c 1 -t 1 $ipnumber > /dev/null
      ok=$?
      eval $statusname=$ok
      if [ ${!statusname} -ne $laststatus ]; then
        # echo $DATE Status changed for $ipnumber
        DATE=$(date '+%d/%m/%Y %H:%M:%S')
        if [ $ok -eq 0 ]; then
          echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;32m Node |"$ipnumber "| UP \033[0m" | column -t -s "|"
        else
          echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;31m Node |"$ipnumber "| DOWN \033[0m" | column -t -s "|"
        fi
      fi
      i=$(($i + 1))
    done
   # sleep 1
  done
}

function duck_art {

textred=$(tput setaf 1)
textcyan=$(tput setaf 12)
textyellow=$(tput setaf 11)
textpurple=$(tput setaf 4)
textpink=$(tput setaf 5)
textwhite=$(tput setaf 7)
textgray=$(tput setaf 8)
textgreen=$(tput setaf 10)


echo -e ${textpink} ================================================================
cat <<EOM
${textyellow}
EOM
cat << "EOF"
                  __                         __
              ___( o)>       DuckLab       <(o )___
              \ <_. )        Monitor        ( ._> /
               `---'                         `---' 
EOF
echo -e ${textpink} ================================================================
echo -e ${textyellow} "                    Press <CTRL+C> to exit.                   "
echo -e ${textpink} ================================================================
echo -e "\033[1;36m  $internal_ip \033[0m" "     ${textpink}|     " "\033[1;36m $my_name \033[0m" "     ${textpink}|     " "\033[1;36m $external_ip \033[0m"
echo -e ${textpink} ================================================================
}


external_ip=$(curl -s ifconfig.me)

internal_ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')

my_name=$(hostname)



function multi_process_live {
T="$(date +%s%N)"

DEFAULT_NO_OF_PROC=8
noofproc=$DEFAULT_NO_OF_PROC

if [ -n "$2" ] #user-set no. of process instead of default
  then
    noofproc=$2
    echo "Max processes: $noofproc"
  fi

export -f check_live && cat $hosts | xargs -n 1 -P $noofproc -I{} bash -c 'check_live  {}' \; 2>/dev/null 
}



function multi_process_health {
T="$(date +%s%N)"

DEFAULT_NO_OF_PROC=8
noofproc=$DEFAULT_NO_OF_PROC

if [ -n "$2" ] #user-set no. of process instead of default
  then
    noofproc=$2
    echo "Max processes: $noofproc"
  fi

export -f check_health && cat $hosts | xargs -n 1 -P $noofproc -I{} bash -c 'check_health  {}' \; 2>/dev/null 
}



# ================================ End of fucntions ================================

# ================================ Start of Script =================================

clear
duck_art
multi_process_live
multi_process_health

# ================================ End of Script ===================================

首先檢查活動主機的 function 工作正常。 第二個循環的 function 顯示初始 output 但沒有正確循環遍歷文件的每一行以監視哪些主機是 UP 或 Down 並打印 output。 它僅針對第二行執行此操作,我假設它沒有正確讀取文件的每一行。

任何使這項工作和學習的想法、改進和建議都受到高度重視。

謝謝你。

請注意,原始腳本的魔力在於使用xargs -P $noofproc並行運行檢查。

在不知道您的主機列表是什么樣子的情況下,很難猜測您在第一行看到的問題是什么。 我最好的猜測是,對於您的第一個條目, ping退出代碼是非零的,它只是沒有退出任何東西。

我發現您最近的check_health function 存在一些問題。

  • 正如您所指出的, while true循環
  • for ipnumber in "$*"沒有任何意義,因為無論如何你一次只用一個條目來調用它。
  • 隨之而來的問題是,對check_health的每次調用都以i=1開頭,因此即使沒有while true ,每個調用都會設置相同的狀態名稱( statusnameup1會被使用。

這是我的建議(我希望你不介意我從你的腳本中刪除了非必要的部分):

#!/bin/bash

trap exit 2

argc=$#
if [ $# -lt 1 ]; then
    echo "Usage: $0 <ip-list-file>"
    exit 1
fi

hosts=$1

function check_live {
    trap exit 2

    DATE=$(date '+%d/%m/%Y %H:%M:%S')
    ping -c 1 -t 1 $1 > /dev/null
    [ $? -eq 0 ] && echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;32m Node |"$1 "| UP \033[0m" | column -t -s "|"
}

function check_health {
    trap exit 2

    i=$1
    ipnumber=$2
    statusname=up$1
    laststatus=${!statusname:-0}
    ping -c 1 -t 1 $ipnumber > /dev/null
    ok=$?
    eval $statusname=$ok
    if [ ${!statusname} -ne $laststatus ]; then
        DATE=$(date '+%d/%m/%Y %H:%M:%S')
        if [ $ok -eq 0 ]; then
            echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;32m Node |"$ipnumber "| UP \033[0m" | column -t -s "|"
        else
            echo -e "|\033[1;36m  $DATE \033[0m" "|\033[1;31m Node |"$ipnumber "| DOWN \033[0m" | column -t -s "|"
        fi
    fi
}

function multi_process_live {
    T="$(date +%s%N)"

    DEFAULT_NO_OF_PROC=8
    noofproc=$DEFAULT_NO_OF_PROC

    if [ -n "$2" ]; then
        #user-set no. of process instead of default
        noofproc=$2
        echo "Max processes: $noofproc"
    fi

    export -f check_live
    cat $hosts | xargs -n 1 -P $noofproc -I{} bash -c 'check_live  {}' \; 2>/dev/null
}

function multi_process_health {
    T="$(date +%s%N)"

    DEFAULT_NO_OF_PROC=8
    noofproc=$DEFAULT_NO_OF_PROC

    if [ -n "$2" ]; then
        #user-set no. of process instead of default
        noofproc=$2
        echo "Max processes: $noofproc"
    fi

    export -f check_health
    awk '{print FNR " " $1}' < $hosts | xargs -n2 -P $noofproc -I{} bash -c 'check_health  {}' \; 2>/dev/null
}

multi_process_live
while true; do
    multi_process_health
    sleep 1
done

這將運行初始實時檢查,然后運行 ​​multi_process_health function。

關鍵是兩件事。 首先使用awk '{print FNR " " $1}'來轉換主機列表:

127.0.0.1
10.0.0.1
192.168.0.1

進入這個:

1 127.0.0.1
2 10.0.0.1
3 192.168.0.1

其次,使用xargs -n2使得每次調用check_health都將序列號作為第一個參數,將實際主機作為第二個參數。

如果主機數量適合您的屏幕,請嘗試以下操作:

healthcheck() {
    ipnumber=$1
    last="-1"
    while true; do
        date=$(date -Is)
        ping -c 1 -t 20 $ipnumber > /dev/null 2>/dev/null
        latest=$?
        if [ $last -ne $latest ] ; then
            # status changed                                                                                                                        
            if [ $latest -eq 0 ] ; then
                echo -e "|\033[1;36m  $date \033[0m" "|\033[1;32m Node |"$ipnumber "| UP \033[0m" | column -t -s "|"
            else
                echo -e "|\033[1;36m  $date \033[0m" "|\033[1;31m Node |"$ipnumber "| DOWN \033[0m" | column -t -s "|"
            fi
        fi
        last=$latest
        sleep 1
    done
}
export -f healthcheck

cat hostlist | parallel-20220622 -j0 --ll healthcheck

如果您沒有 parallel-20220622,這可能就足夠了:

cat hostlist | parallel -j0 --lb healthcheck

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM