Как я могу прочитать 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
этот так называемый шебанг определяет, с какой оболочки должен запускаться ваш скрипт, здесьbash
while IFS='' read -r l || [ -n "$l" ]; do stuff; done < "urls"
read
файл с именемurls
построчно, присваивая переменную содержимое текущей строкиl
и делатьstuff
с этимping -q -w 10 "$l"
знак равноping -qw10 "$l"
)
вызовping
с содержанием переменнойl
в качестве аргумента и вариантов-q
Uiet (меньше продукции нам не нужно) и-w 10
(время ожидания в секундах), поэтому обрабатываемый в данный момент URL-адрес проверяется точно10
секунд - вы можете настроить это значение в соответствии со своими потребностями, а также указать другие параметры (см.man ping
) для списка)avg=$(ping … | sed …)
труба на выходеping
вsed
который сокращает среднее время ответа и сохраняет это значение в переменнойavg
sed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_'
sed '$!d
не (!
)d
выберите последнюю строку ($
) но все остальноеsed 's/a/b/'
s
ubstitutea
от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