Как я могу написать сценарий linux bash, который говорит мне, какие компьютеры включены в моей локальной сети?

Как я могу написать сценарий Linux bash, который говорит мне, какие компьютеры включены в моей локальной сети ?

это помогло бы, если бы я мог дать ему в качестве входного диапазона IP.

16 ответов


я бы предложил использовать флаг пинг-сканирования nmap,

$ nmap -sn 192.168.1.60-70

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2009-04-09 20:13 BST
Host machine1.home (192.168.1.64) appears to be up.
Host machine2.home (192.168.1.65) appears to be up.
Nmap finished: 11 IP addresses (2 hosts up) scanned in 0.235 seconds

тем не менее, если вы хотите написать это сами (что достаточно справедливо), вот как я бы это сделал:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done

..и объяснение каждого бита приведенной выше команды:

создание списка IP-адресов

вы можете использовать {1..10} синтаксис для создания списка чисел, например..

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

(это также полезно для таких вещей, как mkdir {dir1,dir2}/{sub1,sub2} - что делает dir1 и dir2, содержащих sub1 и sub2)

Итак, чтобы создать список IP-адресов, мы сделаем что-то вроде

$ echo 192.168.1.{1..10}
192.168.1.1 192.168.1.2 [...] 192.168.1.10

петли

чтобы зациклиться на чем-то в bash, вы используете for:

$ for thingy in 1 2 3; do echo $thingy; done
1
2
3

пинг

далее, чтобы пинг.. Команда ping немного отличается от разных операционных систем, разных дистрибутивов / версий (в настоящее время я использую OS X)

по умолчанию (опять же, в версии OS X из ping) он будет пинговать, пока не прервется, что не будет работать для этого, так что ping -c 1 будет пытаться отправить только один пакет, которого должно быть достаточно, чтобы определить, работает ли машина.

еще одна проблема-значение тайм-аута, которое, кажется, составляет 11 секунд в этой версии ping.. Он изменен с помощью -t флаг. Одной секунды должно быть достаточно, чтобы увидеть, жива ли машина в локальной сети или нет.

Итак, команда ping мы будем использовать есть..

$ ping -c 1 -t 1 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

проверка результата пинга

Далее, нам нужно знать, ответила ли машина или нет..

мы можем использовать && оператор для выполнения команды, если первая успешно, например:

$ echo && echo "It works"

It works
$ nonexistantcommand && echo "This should not echo"
-bash: nonexistantcommand: command not found

хорошая, так что мы можем сделать..

ping-c 1-t 1 192.168.1.1 && echo "192.168.1.1 вверх!"

другой способ-использовать код выхода из ping.. Команда ping выйдет с кодом exit-code 0 (success), если она работал, и ненулевой код, если он не. В bash вы получаете последние команды выхода кода с переменной $?

Итак, чтобы проверить, работает ли команда, мы сделаем это..

ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi

скрытие вывода ping

последнее, нам не нужно видеть вывод ping, поэтому мы можем перенаправить stdout to /dev/null С > редирект, например:

$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up"
IP is up

и направить stderr (отбросить ping: sendto: Host is down сообщения), вы используете 2> - для пример:

$ errorcausingcommand
-bash: errorcausingcommand: command not found
$ errorcausingcommand 2> /dev/null
$

скрипт

Итак, чтобы объединить все это..

for ip in 192.168.1.{1..10}; do  # for loop and the {} operator
    ping -c 1 -t 1 192.168.1.1 > /dev/null 2> /dev/null  # ping and discard output
    if [ $? -eq 0 ]; then  # check the exit code
        echo "${ip} is up" # display the output
        # you could send this to a log file by using the >>pinglog.txt redirect
    else
        echo "${ip} is down"
    fi
done

или, используя && метод, в одной строке:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done

это медленно.. Каждая команда ping занимает около 1 секунды (так как мы устанавливаем флаг-t timeout в 1 секунду). Он может запускать только одну команду ping за раз.. Очевидный способ обойти это-использовать потоки, поэтому вы можете запускать параллельные команды, но это выходит за рамки того, что вы должны использовать bash для..

"Python threads - первый пример" объясняет, как использовать модуль Python threading для записи многопоточного ping'ER.. Хотя в этот момент я бы еще раз предложил использовать nmap -sn..


в реальном мире вы можете использовать в Nmap чтобы получить то, что вы хотите.

nmap -sn 10.1.1.1-255

это будет пинговать все адреса в диапазоне от 10.1.1.1 до 10.1.1.255 и даст вам знать, какие из них отвечают.

конечно, если вы действительно хотите сделать это как упражнение bash, вы можете запустить ping для каждого адреса и проанализировать вывод, но это совсем другая история.


предполагая, что моя сеть 10.10.0.0/24, Если я запускаю пинг на широковещательный адрес как

ping -b 10.10.0.255

я получу ответ от всех компьютеров в этой сети, которые не заблокировали их порт ICMP ping.

64 bytes from 10.10.0.6: icmp_seq=1 ttl=64 time=0.000 ms
64 bytes from 10.10.0.12: icmp_seq=1 ttl=64 time=0.000 ms 
64 bytes from 10.10.0.71: icmp_seq=1 ttl=255 time=0.000 ms 

поэтому вам просто нужно извлечь 4-й столбец, например, с awk:

ping -b 10.10.0.255 | grep 'bytes from' | awk '{ print  }'

10.10.0.12:
10.10.0.6:
10.10.0.71:
10.10.0.95:

Ну, вы получите дубликат, и вам может потребоваться удалить':'.

редактировать комментарии : опция-c ограничивает количество запросов поскольку сценарий закончится, мы также можем ограничить себя уникальными IPs

ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print  }' | sort | uniq

появилась fping:

fping -g 192.168.1.0/24

или:

fping -g 192.168.1.0 192.168.1.255

или показывать только живые хосты:

fping -ag 192.168.1.0/24

он пингует хосты параллельно, поэтому сканирование происходит очень быстро. Я не знаю дистрибутива, который включает fping в его установке по умолчанию, но в большинстве дистрибутивов вы можете получить его через Диспетчер пакетов.


также используя метод "ping the broadcast address", указанный chburd, эта труба должна сделать трюк для вас:

ping -c 5 -b 10.11.255.255 | sed -n 's/.* \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*//p' | sort | uniq

конечно, вам придется изменить широковещательный адрес на адрес вашей сети.


просто для удовольствия, вот альтернативный

     #!/bin/bash
     nmap -sP 192.168.1.0/24 > /dev/null 2>&1 && arp -an | grep -v incomplete | awk '{print}' | sed -e s,\(,, | sed -e s,\),,


Если вы ограничиваете себя только изменением последнего октета, этот скрипт должен это сделать. Должно быть довольно очевидно, как расширить его от одного до нескольких октетов.

#! /bin/bash
BASE=
START=
END=

counter=$START

while [ $counter -le $END ]
do
  ip=$BASE.$counter
  if ping -qc 2 $ip
  then
    echo "$ip responds"
  fi
  counter=$(( $counter + 1 ))
done


как указывали другие плакаты,nmap это путь, но вот как сделать эквивалент сканирования ping в bash. Я бы не использовал широковещательный пинг, так как в настоящее время многие системы настроены не реагировать на широковещательный ICMP.

for i in $(seq 1 254); do
    host="192.168.100.$i"
    ping -c 1 -W 1 $host &> /dev/null
    echo -n "Host $host is "
    test $? -eq 0 && echo "up" || echo "down"
done

#!/bin/bash
#Get the ip address for the range
ip=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print }' | cut -d"." -f1,2,3)

# ping test and list the hosts and echo the info

for range in $ip ; do  [ $? -eq 0 ] && ping -c 1 -w 1 $range > /dev/null 2> /dev/null && echo "Node $range is up" 
done

хотя это старый вопрос, он все еще кажется важным (по крайней мере, достаточно важным для меня, чтобы справиться с этим). Мой скрипт также полагается на nmap, поэтому здесь нет ничего особенного, кроме того, что ou может определить, какой интерфейс вы хотите сканировать, и диапазон IP создается автоматически (по крайней мере, вид).

вот что я придумал

#!/bin/bash
#Script for scanning the (local) network for other computers 

command -v nmap >/dev/null 2>&1 || { echo "I require nmap but it's not installed. Aborting." >&2; exit 1; }

if [ -n ""$@"" ];  then
    ip=$(/sbin/ifconfig  | grep 'inet '  | awk '{ print }' | cut -d"." -f1,2,3 )
    nmap -sP $ip.1-255
else
    echo -e "\nThis is a script for scanning the (local) network for other computers.\n"
    echo "Enter Interface as parameter like this:"
    echo -e "\t./scannetwork.sh $(ifconfig -lu | awk '{print }')\n"

    echo "Possible interfaces which are up are: "   
    for i in $(ifconfig -lu)
    do
        echo -e "3[32m \t $i 3[39;49m"
    done

    echo "Interfaces which could be used but are down at the moment: "
    for i in $(ifconfig -ld)
    do
        echo -e "3[31m \t $i 3[39;49m"
    done
    echo
fi

одно замечание: этот скрипт создан на OSX, поэтому могут быть некоторые изменения в средах linux.


если вы хотите предоставить список хостов, это можно сделать с помощью nmap, grep и awk.

установить nmap:

$ sudo apt-get install nmap

создать файл hostcheck.sh вот так:

hostcheck.sh

#!/bin/bash

nmap -sP -iL hostlist -oG pingscan > /dev/null
grep Up pingscan | awk '{print }' > uplist
grep Down pingscan | awk '{print }' > downlist

- sP: Ping Scan-не идти дальше, чем определение, если хост находится в сети

- iL: вход из списка хостов / сетей

- oG: вывод результатов сканирования в формате Grepable в заданное имя файла.

/dev / null: отбрасывает вывод

изменить разрешение доступа:

$ chmod 775 hostcheck.sh

создать файл hostlist со списком хостов для проверки (имя хоста или IP):

hostlist (пример)

192.168.1.1-5
192.168.1.101
192.168.1.123

192.168.1.1-5-это диапазон IPs

выполнить скрипт:

./hostcheck.sh hostfile

будут сгенерированы файлы pingscan со всей информацией, uplist с хостами онлайн (вверх) и downlist с хостами в автономном режиме (Вниз.)

uplist (пример)

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.101

downlist (пример)

192.168.1.5
192.168.1.123

некоторые машины не отвечают на пинги (например, межсетевые экраны).

если вы хотите только локальную сеть, вы можете использовать эту команду:

(for n in $(seq 1 254);do sudo arping -c1 10.0.0.$n &  done ; wait) | grep reply | grep --color -E '([0-9]+\.){3}[0-9]+'

пояснении !

  1. arping - это команда, которая отправляет запросы ARP. Он присутствует на большинстве linux.

пример:

sudo arping -c1 10.0.0.14

sudo не является необходимым, если вы корень ofc.

  • 10.0.0.14: ip, который вы хотите тест
  • -c1 : отправить всего один запрос.

  1. &: символ "я-не-хочу-ждать"

это действительно полезный символ, который дает вам возможность запускать команду в подпроцессе, не дожидаясь его завершения (например, поток)


  1. the for loop здесь для arping всех 255 ip-адресов. Он использует seq команда для перечисления всех числа.

  1. wait: после того, как мы запустили наши запросы, мы хотим посмотреть, есть ли ответы. Для этого мы просто ставим wait после цикла. wait похоже на функцию join() в других языках.

  1. (): скобки здесь, чтобы интерпретировать все выходы как текст, чтобы мы могли дать его grep

  1. grep: мы хотим видеть ответы. второй grep просто здесь, чтобы выделить IPs.

hth

Edit 20150417: Обновление Maxi !

плохая часть моего решения заключается в том, что он печатает все результаты в конце. Это потому, что у grep есть достаточно большой буфер, чтобы поместить некоторые строки внутрь. решение состоит в том, чтобы добавить --line-buffered к первому grep. вот так:

(for n in $(seq 1 254);do sudo arping -c1 10.0.0.$n &  done ; wait) | grep --line-buffered reply | grep --color -E '([0-9]+\.){3}[0-9]+'

#!/bin/bash

for ((n=0 ; n < 30 ; n+=1))
do
    ip=10.1.1.$n
    if ping -c 1 -w 1 $ip > /dev/null 2> /dev/null >> /etc/logping.txt; then  
        echo "${ip} is up" # output up
        # sintax >> /etc/logping.txt log with .txt format
    else
        echo "${ip} is down" # output down
    fi
done

следующий (злой) код выполняется более чем в два раза быстрее, чем метод nmap

for i in {1..254} ;do (ping 192.168.1.$i -c 1 -w 5  >/dev/null && echo "192.168.1.$i" &) ;done

занимает около 10 секунд, где стандартный nmap

nmap -sP 192.168.1.1-254

занимает 25 секунд...


Ну, это часть моего сценария.

ship.sh простой, удобный сетевой адресации мультитул с большим количеством функций

pings network, отображает онлайн-хосты в этой сети с их локальным IP и MAC-адресом

это не требует редактирования. Требуется разрешение root для запуска.

GOOGLE_DNS="8.8.8.8"
ONLINE_INTERFACE=$(ip route get "${GOOGLE_DNS}" | awk -F 'dev ' 'NR == 1 {split(, a, " "); print a[1]}')
NETWORK_IP=$(ip route | awk "/${ONLINE_INTERFACE}/ && /src/ {print $1}" | cut --fields=1 --delimiter="/")
NETWORK_IP_CIDR=$(ip route | awk "/${ONLINE_INTERFACE}/ && /src/ {print $1}")
FILTERED_IP=$(echo "${NETWORK_IP}" | awk 'BEGIN{FS=OFS="."} NF--')

ip -statistics neighbour flush all &>/dev/null

echo -ne "Pinging ${NETWORK_IP_CIDR}, please wait ..."
for HOST in {1..254}; do
  ping "${FILTERED_IP}.${HOST}" -c 1 -w 10 &>/dev/null &
done

for JOB in $(jobs -p); do wait "${JOB}"; done

ip neighbour | \
    awk 'tolower() ~ /reachable|stale|delay|probe/{printf ("%5s\t%s\n", , )}' | \
      sort --version-sort --unique