Как получить процент пакетов, полученных от Ping в bash? - PullRequest
5 голосов
/ 29 ноября 2011

При пинге хоста я хочу, чтобы мои выходные данные просто отображали процент полученных (5 отправленных) пакетов.Я предполагаю, что мне нужно как-то использовать grep, но я не могу понять, как (я новичок в программировании Bash).Вот где я нахожусь: ping -c 5 -q $host | grep ?.Что должно идти в grep?Я думаю, что мне придется сделать некоторую арифметику, чтобы получить полученный процент, но я могу справиться с этим.Как я могу извлечь нужную мне информацию из сводки, которую выведет ping?

Ответы [ 6 ]

9 голосов
/ 21 августа 2014

Пока что мы получили ответ, используя grep, sed, perl, bc и bash.Вот один из вариантов AWK , «интерпретируемого языка программирования, предназначенного для обработки текста».Этот подход предназначен для просмотра / сбора информации о потере пакетов в режиме реального времени с использованием ping .

Для просмотра только информации о потере пакетов:

Команда

$ ping google.com | awk '{ sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; } { if (sent>0) loss=100-((received/sent)*100) } { printf "sent:%d received:%d loss:%d%%\n", sent, received, loss }'

Вывод

sent:0 received:0 loss:0%
sent:1 received:1 loss:0%
sent:2 received:2 loss:0%
sent:3 received:2 loss:33%
sent:4 received:2 loss:50%
sent:5 received:3 loss:40%
^C

Тем не менее, я считаю полезным также увидеть исходный ввод.Для этого вы просто добавляете print $0; к последнему блоку в скрипте:

Команда

$ ping google.com | awk '{ sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; } { if (sent>0) loss=100-((received/sent)*100) } { print $0; printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; }'

Вывод

PING google.com (173.194.33.104): 56 data bytes
sent:0 received:0 loss:0%
64 bytes from 173.194.33.46: icmp_seq=0 ttl=55 time=18.314 ms
sent:1 received:1 loss:0%
64 bytes from 173.194.33.46: icmp_seq=1 ttl=55 time=31.477 ms
sent:2 received:2 loss:0%
Request timeout for icmp_seq 2
sent:3 received:2 loss:33%
Request timeout for icmp_seq 3
sent:4 received:2 loss:50%
64 bytes from 173.194.33.46: icmp_seq=4 ttl=55 time=20.397 ms
sent:5 received:3 loss:40%
^C

Как все это работает?

Вы прочитали команду, попробовали, и она работает!Так что именно происходит?

$ ping google.com | awk '...'

Мы начинаем с pinging google.com и , отправляя вывод в awk, интерпретатор.Все, что в одинарных кавычках, определяет логику нашего сценария.

Вот он в удобном для пробелов формате:

# Gather Data
{
  sent=NR-1;
  received+=/^.*(time=.+ ms).*$/;
  loss=0;
}

# Calculate Loss
{
  if (sent>0) loss=100-((received/sent)*100)
}

# Output
{
  print $0; # remove this line if you don't want the original input displayed
  printf "sent:%d received:%d loss:%d%%\n", sent, received, loss;
}

Мы можем разбить его на три составляющие:

{ gather data } { calculate loss } { output }

Каждый раз, когда ping выводит информацию, скрипт AWK использует ее и запускает эту логику против нее.

Сбор данных

{ sent=NR-1; received+=/^.*(time=.+ ms).*$/; loss=0; }

У этого есть три действия;определение переменных sent, received и loss.

sent=NR-1;

NR - это переменная AWK для текущего числа записей.В AWK запись соответствует строке.В нашем случае одна строка вывода из пинга.Первая строка вывода ping является заголовком и не представляет фактический запрос ICMP.Итак, мы создаем переменную sent и присваиваем ей текущий номер строки минус один.

received+=/^.*(time=.+ ms).*$/;

Здесь мы используем Регулярное выражение , ^.*(time=.+ ms).*$, чтобы определить, является лиЗапрос ICMP был успешным или нет.Поскольку каждый успешный пинг возвращает время, которое потребовалось, мы используем его в качестве нашего ключа.

Для тех, кто не очень хорошо разбирается в шаблонах регулярных выражений, это то, что означает наше:

  1. ^ начиная с начала строки
  2. .* соответствует чему-либо до следующего правила
  3. (time=.+ ms) соответствует "время = N мс", где N может быть один или нескольколюбого символа
  4. .* соответствует чему-либо до следующего правила
  5. $ остановка в конце строки

Когда образец сопоставляется, мыувеличить переменную received.

Рассчитать потери

{ if (sent>0) loss=100-((received/sent)*100) }

Теперь, когда мы знаем, сколько ICMP-запросов было отправлено и получено, мы можем приступить к выполнению математических операций для определения потери пакетов.Чтобы избежать ошибки деления на ноль , перед выполнением каких-либо вычислений мы отправляем запрос.Сам расчет довольно прост:

  1. received/sent = процент успеха в десятичном формате
  2. *100 = преобразование из десятичного в целочисленный формат
  3. 100- = инвертировать процент от успеха к неудаче

Вывод

{ print $0; printf "sent:%d received:%d loss:%d%%\n", sent, received, loss; }

Наконец, нам просто нужно напечатать соответствующую информацию.


Я неЯ не хочу помнить все это

Вместо того, чтобы вводить это каждый раз или искать этот ответ, вы можете сохранить скрипт в файл (например, packet_loss.awk).Тогда все, что вам нужно набрать:

$ ping google.com | awk -f packet_loss.awk
9 голосов
/ 29 ноября 2011

Как всегда, есть много разных способов сделать это, но вот один из вариантов:

Это выражение будет захватывать процентные цифры от "X% потери пакета"

ping -c 5 -q $host | grep -oP '\d+(?=% packet loss)'

Затем вы можете вычесть процент «потерь» из 100, чтобы получить процент «успеха»:

packet_loss=$(ping -c 5 -q $host | grep -oP '\d+(?=% packet loss)')
echo $[100 - $packet_loss]
3 голосов
/ 29 ноября 2011

Предполагая, что результаты вашего пинга выглядят следующим образом:

PING host.example (192.168.0.10) 56(84) bytes of data.

--- host.example ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.209/0.217/0.231/0.018 ms

Передача ping -c 5 -q через:

grep -E -o '[0-9]+ received' | cut -f1 -d' '

Выход:

5

И тогда вы можетевыполнить свою арифметику.

1 голос
/ 29 ноября 2011
echo $((100-$(ping -c 5 -q www.google.hu | sed -rn "/packet loss/ s@.*([0-9]+)%.*@\1@p")))
0 голосов
/ 29 ноября 2011

Это у вас работает?

bc -l <<<100-$(ping -c 5 -q $host |
               grep -o '[0-9]% packet loss' |
               cut -f1 -d% )

Происходит процент, сообщенный ping, и вычитает его из 100, чтобы получить процент полученных пакетов.

0 голосов
/ 29 ноября 2011

Попробуйте скрипт:

/bin/bash
rec=ping -c $1 -q $2 | grep -c "$2" | sed -r 's_$_ / \$1_' | xargs expr

Сохраните его и запустите с двумя аргументами командной строки. Первый - это количество пакетов, второй - хост.

...