Пока что мы получили ответ, используя 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 был успешным или нет.Поскольку каждый успешный пинг возвращает время, которое потребовалось, мы используем его в качестве нашего ключа.
Для тех, кто не очень хорошо разбирается в шаблонах регулярных выражений, это то, что означает наше:
^
начиная с начала строки .*
соответствует чему-либо до следующего правила (time=.+ ms)
соответствует "время = N мс", где N может быть один или нескольколюбого символа .*
соответствует чему-либо до следующего правила $
остановка в конце строки
Когда образец сопоставляется, мыувеличить переменную received
.
Рассчитать потери
{ if (sent>0) loss=100-((received/sent)*100) }
Теперь, когда мы знаем, сколько ICMP-запросов было отправлено и получено, мы можем приступить к выполнению математических операций для определения потери пакетов.Чтобы избежать ошибки деления на ноль , перед выполнением каких-либо вычислений мы отправляем запрос.Сам расчет довольно прост:
received/sent
= процент успеха в десятичном формате *100
= преобразование из десятичного в целочисленный формат 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