Question Comment lire des URL sur des lignes distinctes dans un fichier .txt et envoyer des requêtes ping à chacune


j'ai un .txt fichier avec 5 urls dedans. Je veux le lire ligne par ligne et effectuer 4 requêtes ping pour chaque site et extraire l'heure. Le code que j'ai écrit est ci-dessous, mais cela ne fonctionne pas.

Quelqu'un peut-il me donner un indice?

#!/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 

6
2017-11-17 13:12


origine




Réponses:


Ceci aussi bien que Réponse de Sergiy est venu de Bouclez le fichier texte avec les URL et exécutez le ping sur chaque.

En supposant le fichier urls réside dans le répertoire en cours et contient vos URL seulement, un par ligne:

#!/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"

Exemple d'exécution

Le script ci-dessus a été nommé avg ici.

$ cat urls
askubuntu.com
unix.stackexchange.com
stackoverflow.com
$ ./avg
$ cat avg_time 
Average respond time for askubuntu.com: 37.742 ms
Average respond time for unix.stackexchange.com: 35.966 ms
Average respond time for stackoverflow.com: 38.982 ms

Des explications

  • #!/bin/bash
    ce soi-disant case définit le shell avec lequel votre script doit être démarré, ici c'est bash
  • while IFS='' read -r l || [ -n "$l" ]; do des trucs; done < "urls"
    read le fichier nommé urls ligne par ligne, affectant le contenu de la ligne en cours de traitement à la variable l et faire stuff avec ça
  • ping -q -w 10 "$l" (= = ping -qw10 "$l")
    appel ping avec le contenu de la variable l comme argument et les options -quiet (moins de production dont nous n’avons pas besoin) et -w 10 (délai d'attente en secondes), de sorte que l'URL actuellement traitée soit envoyée avec un ping exact 10 secondes - vous pouvez ajuster cette valeur à vos besoins et spécifier d'autres options (voir man ping) pour la liste)
  • avg=$(ping … | sed …)
    pipe la sortie de ping à sed qui supprime le temps de réponse moyen et enregistre cette valeur dans la variable avg

    • sed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_'
    • sed '$!d
      ne pas (!) delete la dernière ligne ($), mais tout le reste
    • sed 's/a/b/'
      substitute a par b - peut également être écrit par ex. sed 's_a_b_' si cela est utile, nous n'avons pas besoin d'échapper à des caractères de barre oblique littérale dans les chaînes
      • .* - Prenez tout
      • = et / - un littéral "=" et "/"
      • [^/]* - Prenez tout ce qui ne l'est pas (^) une barre oblique
      • \([^/]*\) - Prenez tout ce qui ne l'est pas (^) une barre oblique et la sauvegarder dans un groupe
      • \1 - le premier groupe enregistré avec \(…\) avant
    • le même travail pourrait aussi être fait avec awk -F/ '/^rtt/{print$5}':
      • -F/ - définir / comme le Fdélimiteur de champ
      • /^rtt/{…} - sélectionnez le début de la ligne (^) avec «rtt» et faire  avec ça
      • print$5 - print seul champ no. 5
  • echo "Average respond time for $l: $avg ms" >> avg_time
    imprimer le texte en insérant le contenu des variables l et avg et rediriger cette sortie vers le fichier avg_time ajouter à son contenu


8
2017-11-11 13:50



Pouvez-vous me donner des explications supplémentaires sur cette partie du code? sed '$! d; s _. * = [^ /] * / ([^ /] *) /.*\1') - Akis Tachmatzidis
@AkisTachmatzidis Mon plaisir! J'ai ajouté des explications détaillées pour le sed expressions et une awk alternative aussi. Vous êtes invités à me rencontrer à ce salon de discussion pour plus d'explications ou autre aide. - dessert


Pour une simple commande simple telle que ping , on peut utiliser xargs. La chose cool à propos de xargs est-ce qu'il a --arg-file option qui vous permet de spécifier le fichier qui xargs utilisera pour fournir des paramètres de position à la commande que vous essayez d'exécuter; dans votre cas, ce serait un site par ligne dans le fichier texte.

Plus précisément, la commande que vous souhaitez est la suivante:

xargs -I% --arg-file=./input.txt  ping -c 4 %
  • -I nous permet de choisir un emplacement pour chaque argument, qui xargs en interne sera
  • --arg-file est le fichier d'où proviendront les paramètres de position; notez que nous utilisons ./ pour indiquer que le fichier est situé dans le répertoire de travail actuel
  • ping -c 4 va tenter de ping chaque site qui vient de input.txtavec 4 paquets

Notez que nous pouvons également utiliser -q option à ping cela empêchera d'imprimer une ligne pour chaque paquet reçu / transmis, avec uniquement des statistiques en sortie. A partir de là, nous pouvons encore améliorer la production avec awk ou tout autre utilitaire de traitement de texte (gardez à l’esprit que la sortie sera mise en mémoire tampon lorsqu’elle passera par le canal et attendra ping pour finir et sortir des statistiques, apparaîtra donc un peu lentement sur l'écran):

$ xargs -I% --arg-file=./input.txt  ping -c 4 % -q | awk '/^---/||/avg/'                                                                                     
--- askubuntu.com 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}'                                                         
askubuntu.com
39.809
unix.stackexchange.com
189.557
stackoverflow.com
161.974

7
2017-11-13 07:41