Скрипт пинга с фильтром - PullRequest
       2

Скрипт пинга с фильтром

0 голосов
/ 19 сентября 2018

У меня есть текстовый файл с именами хостов и IP-адресами, такими как один (один IP и одно имя хоста на строку).IP-адреса и имена хостов могут быть разделены пробелами и / или каналом, а имя хоста может быть до или после IP-адреса

10.10.10.10 HW-DL11_C023
11.11.11.11 HW-DL11_C024
10.10.10.13 | HW-DL12_C023
11.11.11.12 | HW-DL12_C024
HW-DL13_C023 11.10.10.10 
HW-DL13_C024 21.11.11.11 
HW-DL14_C023 | 11.10.10.10 
HW-DL14_C024 | 21.11.11.11 

Приведенный ниже скрипт должен иметь возможность пинговать хосты с помощьюобщий знаменатель, например, DL13 (есть два устройства, и он пропингует только эти два).Что я делаю не так, потому что просто не могу заставить его работать?

Сценарий находится в том же каталоге, что и данные;Я не получаю ошибок, и все отформатировано.Сервер Linux.

pingme () {
hostfile="/home/rex/u128789/hostfile.txt"
IFS= mapfile -t  hosts < <(cat $hostfile)
for host in "${hosts[@]}"; do
    match=$(echo "$host" | grep -o "\-$1_" | sed 's/-//' | sed 's/_//')
    if [[ "$match" = "$1" ]]; then
        hostname=$(echo "$host" | awk '{print $2}')
        ping -c1 -W1 $(echo "$host" | awk '{print $1}') > /dev/null
        if [[ $? = 0 ]]; then
            echo "$hostname is alive"
        elif [[ $? = 1 ]]; then
            echo "$hostname is dead"
        fi
    fi
done
}

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Исходный код не обрабатывает разделитель канала или, возможно, обратное имя хоста и IP-адрес во входном файле.Это также делает ненужным использование внешних программ (grep, sed, ...).

Попробуйте:

# Enable extended glob patterns - e.g. +(pattern-list)
shopt -s extglob

function pingme
{
    local -r host_denom=$1

    local -r hostfile=$HOME/u128789/hostfile.txt

    local ipaddr host tmp
    # (Add '|' to the usual characters in IFS)
    while IFS=$'| \t\n' read -r ipaddr host ; do
        # Swap host and IP address if necessary
        if [[ $host == +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]] ; then
            tmp=$host
            host=$ipaddr
            ipaddr=$tmp
        fi

        # Ping the host if its name contains the "denominator"
        if [[ $host == *-"$host_denom"_* ]] ; then
            if ping -c1 -W1 -- "$ipaddr" >/dev/null ; then
                printf '%s is alive\n' "$host"
            else
                printf '%s is dead\n' "$host"
            fi
        fi
    done < "$hostfile"

    return 0
}

pingme DL13

Последняя строка (вызов *Функция 1008 *) является лишь примером, но важно, чтобы код что-то делал.

0 голосов
/ 20 сентября 2018

REX, вам нужно более точно указать, какие IP-адреса вы пытаетесь получить из этого примера.Вы также не пропускаете достаточно времени IMO, и ваш сценарий учитывает регистр, проверяя строку (не главную).В любом случае,

Сначала убедитесь, что ваш ввод и вывод работает правильно, в этом примере я просто читаю и печатаю, если это не работает, разрешения на исправление и т. Д .:

file="/tmp/hostfile.txt"
while IFS= read -r line ;do
        echo $line
done < "${file}"

Затем вместо функции сначала попытайтесь заставить ее работать как скрипт, в этом примере я вручную устанавливаю «match» на DL13, затем читаю каждую строку (как раньше) и (1) match на $ match, если найден, я удаляю'|', а затем считывает строку в массив из 2. Если первый элемент массива представляет собой IP (содержит точки), установите его в качестве IP, а другой в качестве имени хоста, в противном случае установите обратное.Затем запустите тест ping.

# BASH4+ Example:
file="/tmp/hostfile.txt"
match="dl13"
while IFS= read -r line ;do

        # -- check for matching string (e.g. dl13 --
        [[ "${line,,}" =~ "${match,,}" ]] || continue

        # -- We found a match, split out host/ip into vars --
        line=$(echo ${line//|})
        IFS=' ' read -r -a items <<< "$line"
        if [[ "${items[0]}" =~ '.' ]] ;then
            host="${items[1]}" ; ip="${items[0]}"
        else
            host="${items[0]}" ; ip="${items[1]}"
        fi

        # -- Ping test --
        ping -q -c3 "${ip}" > /dev/null
        if [ $? -eq 0 ] ;then
            echo "$host is alive!"
        else
            echo "$host is toast!"
        fi

done < "${file}"
0 голосов
/ 19 сентября 2018

Попробуйте добавить эти две строки в ваш код:

pingme () {
hostfile="/home/rex/u128789/hostfile.txt"
IFS= mapfile -t  hosts < <(cat $hostfile)
for host in "${hosts[@]}"; do
    echo "Hostname: $host"                      # <-------- ADD THIS LINE -------
    match=$(echo "$host" | grep -o "\-$1_" | sed 's/-//' | sed 's/_//')
    echo "...matched with $match"               # <-------- ADD THIS LINE -------
    if [[ "$match" = "$1" ]]; then
        hostname=$(echo "$host" | awk '{print $2}')
        ping -c1 -W1 $(echo "$host" | awk '{print $1}') > /dev/null
        if [[ $? = 0 ]]; then
            echo "$hostname is alive"
        elif [[ $? = 1 ]]; then
            echo "$hostname is dead"
        fi
    fi
done
}

Затем, когда вы запустите его, вы должны увидеть список ваших хостов, по крайней мере.

  • Если нет, значит, вы не читаете свой файл успешно.
  • Если вы это сделаете, в вашей логике каждого хоста есть проблема.

Поздравляем!Вы разделили свою проблему на две меньшие проблемы.Как только вы знаете, у какой половины есть проблема, продолжайте делить проблему пополам, пока наименьшая возможная проблема не бросит вас в глаза.Вы, вероятно, знаете решение в этой точке.Если нет, добавьте свои выводы к вопросу, и мы оттуда поможем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...