J'essaie donc de cingler une plage d'adresses en parallèle dans un script bash, de compter celles qui sont vivantes et de les imprimer. Le script fonctionne pour cingler les adresses et imprimer celles en direct, mais il affiche toujours:
"Il y avait 0 hôtes en ligne et 254 hôtes hors ligne"
Il n'incrémente pas la variable ALIVE dans mon code, peut-être parce que c'est dans un sous-shell? Comment pourrais-je contourner cela? Voici ce que j'ai en ce moment:
#!/bin/bash if [ $# -eq 3 ] then TOTAL=0 #NEW TEMP=mktemp #NEW echo -n 'Live hosts:' for ((i = $2; i <= $3 && i <= 254; ++i)) do ((++TOTAL)) ping -c 1 -i 0.2 -w 1 -W 1 $1.$i > /dev/null && echo " $1.$i" >> $TEMP & #NEW done wait #NEW cat $TEMP ALIVE=$(cat $TEMP | wc -l) #NEW echo "There were $ALIVE online hosts and $((($TOTAL - $ALIVE))) offline hosts" rm $TEMP #NEW else echo "USAGE: pingRange.sh <first 3 octets of ip> <last octet start> <last octet end>" echo " Ex: pingRange.sh 192.168.0 1 254
Remarque: Un exemple d'entrée pour le script est affiché dans la partie "else".
Note 2: Oui Je sais que nmap est plus facile, j'ai déjà écrit un script de travail avec nmap, en essayant d'en faire un pour le ping maintenant.
Note 3: J'ai utilisé un fichier temporaire et cela a fonctionné, le code mis à jour a un commentaire #NEW :
#!/bin/bash TOTAL=0 ALIVE=0 if [ $# -eq 3 ] then echo -n 'Live hosts:' for ((i = $2; i <= $3 && i <= 254; ++i)) do ((++TOTAL)) ping -c 1 -i 0.2 -w 1 -W 1 $1.$i > /dev/null && ((++ALIVE)) && echo " $1.$i" & done echo "There were $ALIVE online hosts and $((($TOTAL - $ALIVE))) offline hosts" else echo "USAGE: pingRange.sh <first 3 octets of ip> <last octet start> <last octet end>" echo " Ex: pingRange.sh 192.168.0 1 254
4 Réponses :
live_hosts=$(seq -f "$1.%.0f" "$2" "$3" | xargs -n1 -P0 -- sh -c 'ping -c 1 -i 0.2 -w 1 -W 1 "$1" >/dev/null && echo "$1"' --) alive=$(echo "$live_hosts" | wc -l) # well, if just the count matters, add the `| wc -l` to the one liner ..
Je ne pense pas que ce soit tout à fait vrai; &&
ne crée pas de sous-shell, &
le fait.
Pourquoi ne pas utiliser nmap -sn ...
au lieu d'essayer d'écrire un script?
@RedCricket OP a spécifiquement déclaré qu'il avait fait nmap et qu'il était intéressé par une solution bash utilisant ping.
@KamilCuk utilisant nmap -sn
est un ping.
@RedCricket Oui, j'ai utilisé nmap -sn
dans une autre implémentation, cette question posait spécifiquement sur l'utilisation de la commande ping
.
Notez que l'utilisation de la sortie de xargs -P
n'est généralement pas sûre: mywiki.wooledge.org/...
Je pense que vous pouvez le faire simplement en utilisant wait
.
Modifier votre code, quelque chose comme (non testé):
#!/bin/bash TOTAL=0 ALIVE=0 if [ $# -eq 3 ] then unset pids declare -A pids echo -n 'Live hosts:' for ((i = $2; i <= $3 && i <= 254; ++i)) do ((++TOTAL)) ping -c 1 -i 0.2 -w 1 -W 1 $1.$i > /dev/null & pids[$i]=$! done for i in "${!pids[@]}" do wait ${pids[$i]} && ((++ALIVE)) && echo " $1.$i" done echo "There were $ALIVE online hosts and $((($TOTAL - $ALIVE))) offline hosts" else # ...
unset
/ declare
- juste pour être sûr ping ... &
exécute toujours la commande en arrière-plan pids [$ i] = $!
enregistre son pid for ...
boucle sur les touches wait $ {pids [$ i]}
renvoie l'état de sortie une fois cmd terminé && ...
fait la même chose que précédemment En utilisant GNU Parallel, cela ressemble à ceci:
pingrange() { three=$1 start=$2 end=$3 total=$(($end-$start)) online="$(seq $start $end | parallel -j0 "ping -c 1 -i 0.2 -w 1 -W 1 $three.{} > /dev/null && echo ' $three.{}'")" alive=$(echo "$online" | wc -l) offline=$((total-alive)) echo "$online" echo "There were $alive online hosts and $offline offline hosts" }
Il fonctionne correctement même si votre système ne peut pas exécuter tous les ping
s en parallèle en même temps (par exemple si votre table de processus est presque pleine).
Ou vous pouvez simplement utiliser:
fping -g $three.$start $three.$end
et travailler sur la sortie. Voir man fping pour d'autres options.
p>
Ce serait bien de partager la solution nmap.
C'est la sous-coque, oui. Vous pouvez écrire dans un fichier à la place
Pourquoi ne pas utiliser
nmap
dans votre script? linux.die.net/man/1/nmapDuplicate de unix.stackexchange.com/questions/344360/... La solution la plus simple semble être celle de:
job1 & code1 = $ !; ...; attendez $ code1; ans = $ ?;
Remarque 3 .. cela a fonctionné ..
- vous devriez donc poster cela comme réponse à votre question. Dans votre scriptTEMP = mktemp
TEMP
est littéralement la chaînemktemp
, ie.TEMP = "mktemp"
. Vous voulez queTEMP = $ (mktemp)
exécute la commandemktemp
.@KamilCuk J'ai posté ce que j'ai fait après la note. La réponse que j'ai choisie était plus lisible et avait également une solution qui n'avait pas besoin d'utiliser un fichier temporaire, je l'ai donc sélectionnée comme meilleure réponse à la place.
Lisez la page de manuel. La solution est là.