Как я могу прочитать URL-адреса в отдельных строках в текстовом файле и пинговать каждый
У меня есть .txt файл с 5 URL в нем. Я хочу прочитать его построчно, выполнить 4 запроса ping для каждого сайта и извлечь время. Код, который я написал ниже, но он не работает.
Кто-нибудь может дать мне подсказку?
#!/bin/bash
cat /home/akis/Desktop/sites.txt
declare -i var=1
while read -r line
do
while $var <= 5
do
var2=$((var2+1))
name="$line" | ping -c 4 $name > $var.txt | awk '{ print $8 }' < $var.txt | awk '/time/' > $var2.txt | tr '=' '\t' < $var2.txt | awk '{ print $2 }' > $var2.txt
done
var=$((var+1))
done
2 ответа
Это, а также ответ Сергея пришли из Loop over текстовый файл с URL-адресами и выполнить ping для каждого.
Предполагая файл urls находится в текущем каталоге и содержит только ваши URL, по одному в строке:
#!/bin/bash
while IFS='' read -r l || [ -n "$l" ]; do
avg=$(ping -q -w 10 "$l" | sed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_')
echo "Average respond time for $l: $avg ms" >> avg_time
done < "urls"
Пример запуска
Выше сценарий был назван avg Вот.
$ cat urls
Ask-ubuntu.ru
unix.stackexchange.com
stackoverflow.com
$ ./avg
$ cat avg_time
Average respond time for Ask-ubuntu.ru: 37.742 ms
Average respond time for unix.stackexchange.com: 35.966 ms
Average respond time for stackoverflow.com: 38.982 ms
Пояснения
#!/bin/bash
этот так называемый шебанг определяет, с какой оболочки должен запускаться ваш скрипт, здесьbashwhile IFS='' read -r l || [ -n "$l" ]; do stuff; done < "urls"readфайл с именемurlsпострочно, присваивая переменную содержимое текущей строкиlи делатьstuffс этимping -q -w 10 "$l"знак равноping -qw10 "$l")
вызовpingс содержанием переменнойlв качестве аргумента и вариантов-qUiet (меньше продукции нам не нужно) и-w 10(время ожидания в секундах), поэтому обрабатываемый в данный момент URL-адрес проверяется точно10секунд - вы можете настроить это значение в соответствии со своими потребностями, а также указать другие параметры (см.man ping) для списка)avg=$(ping … | sed …)
труба на выходеpingвsedкоторый сокращает среднее время ответа и сохраняет это значение в переменнойavgsed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_'sed '$!d
не (!)dвыберите последнюю строку ($) но все остальноеsed 's/a/b/'substituteaотb- также может быть написано как, например,sed 's_a_b_'если это полезно, таким образом нам не нужно экранировать буквенные символы косой черты в строках.*- возьми все=а также/- буквальное "=" и "/"[^/]*- бери все что не есть (^) косая черта\([^/]*\)- бери все что не есть (^) косая черта и сохранить его в группе\1- первая группа, сохраненная с\(…\)до
- та же самая работа могла бы быть сделана с
awk -F/ '/^rtt/{print$5}':-F/- определить/какFразделитель полей/^rtt/{…}- выберите начало строки (^) с "RTT" и сделать…с этимprint$5-printтолько поле №5
echo "Average respond time for $l: $avg ms" >> avg_time
печатать текст, вставляя содержимое переменныхlа такжеavgи перенаправить этот вывод в файлavg_timeдобавление к его содержанию
Для одной простой команды, такой как ping можно использовать xargs, Классная вещь о xargs в том что --arg-file опция, которая позволяет указать файл, который xargs будет использовать для предоставления позиционных параметров команде, которую вы пытаетесь запустить; в вашем случае это будет один сайт на строку в текстовом файле.
В частности, команда, которую вы хотите, это:
xargs -I% --arg-file=./input.txt ping -c 4 %
-Iпозволяет нам выбрать заполнитель для каждого аргумента, которыйxargsвнутренне будет--arg-fileфайл, из которого поступят позиционные параметры; обратите внимание, что мы используем./указать, что файл находится в текущем рабочем каталогеping -c 4будет пытатьсяpingкаждый сайт, который приходитinput.txtс 4 пакетами
Обратите внимание, что мы также можем использовать -q возможность ping это предотвратит печать строки для каждого полученного / переданного пакета, с выводом только статистики. Оттуда мы можем очистить вывод еще дальше с awk или любая другая утилита для обработки текста (имейте в виду, что вывод будет буферизован при прохождении через канал и ожидании ping чтобы на самом деле закончить и выводить статистику, поэтому будет отображаться на экране немного медленно):
$ xargs -I% --arg-file=./input.txt ping -c 4 % -q | awk '/^---/||/avg/'
--- Ask-ubuntu.ru ping statistics ---
rtt min/avg/max/mdev = 49.677/73.403/94.312/19.276 ms
--- unix.stackexchange.com ping statistics ---
rtt min/avg/max/mdev = 40.015/59.099/115.545/32.590 ms
--- stackoverflow.com ping statistics ---
rtt min/avg/max/mdev = 40.130/40.878/42.685/1.056 ms
$ xargs -I% --arg-file=./input.txt ping -c 4 % -q | awk -F'[ /]' '/^---/{print $2};/avg/{print $8}'
Ask-ubuntu.ru
39.809
unix.stackexchange.com
189.557
stackoverflow.com
161.974