Как я могу написать linux bash script, который сообщает мне, какие компьютеры включены в моей локальной сети?
Как я могу написать linux bash script, который сообщает мне, какие компьютеры включены в моей локальной сети?
Это помогло бы, если бы я мог указать его как входной диапазон IP-адресов.
Ответы
Ответ 1
Я бы предложил использовать флаг nap ping-scan,
$ 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 -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
Loops
Чтобы перебрать что-то в bash, вы используете for
:
$ for thingy in 1 2 3; do echo $thingy; done
1
2
3
Pinging
Далее, для ping. Команда ping немного отличается от разных операционных систем, разных дистрибутивов/версий (я использую OS X в настоящее время)
По умолчанию (опять же, в версии OS X ping
) он будет 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
Проверка результата ping
Затем нам нужно знать, отвечает ли машина или нет.
Мы можем использовать оператор &&
для запуска команды, если первое выполняется успешно, например:
$ 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 up!"
Другой способ - использовать код выхода из ping. Команда ping выйдет с кодом выхода 0 (успех), если она сработает, и ненулевой код, если он не сработал. В 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
в /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
$
script
Итак, чтобы все это совместить..
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 - первый пример" объясняет, как использовать Pingon threading module для написания многопоточного ping'er. Хотя в этот момент я бы еще раз предложил использовать nmap -sn
..
Ответ 2
В реальном мире вы можете использовать nmap, чтобы получить то, что вы хотите.
nmap -sn 10.1.1.1-255
Это вызовет все адреса в диапазоне от 10.1.1.1 до 10.1.1.255 и сообщит вам, какие из них отвечают.
Конечно, если вы действительно хотите сделать это как упражнение bash, вы можете запустить ping для каждого адреса и проанализировать вывод, но это еще одна история.
Ответ 3
Предполагая, что моя сеть 10.10.0.0/24, если я запускаю пинг по широковещательному адресу, например
ping -b 10.10.0.255
Я получу ответ со всех компьютеров в этой сети, которые не блокировали свой порт IP-протокола ICMP.
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
Итак, вам просто нужно извлечь четвертый столбец с помощью awk, например:
ping -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }'
10.10.0.12:
10.10.0.6:
10.10.0.71:
10.10.0.95:
Ну, вы получите дубликат, и вам может потребоваться удалить ':'.
ИЗМЕНИТЬ из комментариев:
Параметр -c ограничивает количество пинов
поскольку script закончится, мы также можем ограничить себя уникальными IP-адресами
ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq
Ответ 4
Существует также 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
в своей установке по умолчанию, но в большинстве дистрибутивов вы можете получить его через диспетчер пакетов.
Ответ 5
Также используя метод "ping the broadcast address", указанный chburd, этот канал должен сделать трюк для вас:
ping -c 5 -b 10.11.255.255 | sed -n 's/.* \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' | sort | uniq
Конечно, вам нужно будет изменить широковещательный адрес на адрес вашей сети.
Ответ 6
Просто для удовольствия, здесь альтернативный
#!/bin/bash
nmap -sP 192.168.1.0/24 > /dev/null 2>&1 && arp -an | grep -v incomplete | awk '{print$2}' | sed -e s,\(,, | sed -e s,\),,
Ответ 7
Если вы ограничиваете себя только тем, что изменили последний октет, этот script должен это сделать. Должно быть достаточно очевидно, как расширить его от одного до нескольких октетов.
#! /bin/bash
BASE=$1
START=$2
END=$3
counter=$START
while [ $counter -le $END ]
do
ip=$BASE.$counter
if ping -qc 2 $ip
then
echo "$ip responds"
fi
counter=$(( $counter + 1 ))
done
Ответ 8
Ответ 9
Как отмечали другие плакаты, 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
Ответ 10
#!/bin/bash
#Get the ip address for the range
ip=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' | 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
Ответ 11
Хотя старый вопрос, он все еще кажется важным (по крайней мере, достаточно важным для меня, чтобы иметь дело с этим). Мой script тоже полагается на 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 not installed. Aborting." >&2; exit 1; }
if [ -n ""[email protected]"" ]; then
ip=$(/sbin/ifconfig $1 | grep 'inet ' | awk '{ print $2}' | 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 $2}')\n"
echo "Possible interfaces which are up are: "
for i in $(ifconfig -lu)
do
echo -e "\033[32m \t $i \033[39;49m"
done
echo "Interfaces which could be used but are down at the moment: "
for i in $(ifconfig -ld)
do
echo -e "\033[31m \t $i \033[39;49m"
done
echo
fi
Одно замечание: Этот script создается на OSX, поэтому могут быть некоторые изменения в средах Linux.
Ответ 12
Если вы хотите предоставить список хостов, это можно сделать с помощью 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 $2}' > uplist
grep Down pingscan | awk '{print $2}' > downlist
-sP: Ping Scan - идти дальше, чем определять, находится ли хост в сети
-iL: вход из списка хостов/сетей
-oG: результаты вывода результатов в формате Grepable, к указанному имени файла.
/dev/null: Отбрасывает вывод
Измените разрешение доступа:
$ chmod 775 hostcheck.sh
Создайте хост файл файлов со списком проверяемых хостов (имя хоста или IP-адрес):
hostlist (Пример)
192.168.1.1-5
192.168.1.101
192.168.1.123
192.168.1.1-5 - диапазон IP-адресов
Запустите script:
./hostcheck.sh hostfile
Будут сгенерированы файлы pingscan со всей информацией, uplist с хостами онлайн (Up) и списком вниз с хостами офлайн (Down).
uplist (Пример)
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.101
нижний список (пример)
192.168.1.5
192.168.1.123
Ответ 13
Некоторые машины не отвечают на запросы (например, брандмауэры).
Если вам нужна только локальная сеть, вы можете использовать эту команду:
(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]+'
Объяснения часть!
-
arping
- это команда, которая отправляет запросы ARP. Он присутствует на большинстве Linux.
Пример:
sudo arping -c1 10.0.0.14
sudo не требуется, если вы являетесь пользователем root.
-
10.0.0.14
: ip, который вы хотите проверить
-
-c1
: отправить только один запрос.
-
&
: символ 'I-don't-want-to-wait'
Это действительно полезный символ, который дает вам возможность запускать команду в подпроцессе, не дожидаясь его окончания (например, поток)
- цикл
for
находится здесь, чтобы задействовать все 255 IP-адресов. Он использует команду seq
для отображения всех номеров.
-
wait
: после того, как мы запустили наши запросы, мы хотим узнать, есть ли ответы. Для этого просто поместите wait
после цикла.
wait
выглядит как функция join()
на других языках.
-
()
: скобки заключаются здесь в том, чтобы интерпретировать все выходы как текст, чтобы мы могли передать его grep
-
grep
: мы хотим видеть только ответы. второй grep находится здесь, чтобы выделить IP-адреса.
HTH
Изменить 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]+'
Ответ 14
#!/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
Ответ 15
Следующий (злой) код работает больше, чем TWICE так же быстро, как метод 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 секунд...
Ответ 16
Ну, это часть моего script.
ship.sh 🚢 Простая, удобная сетевая адресация 🔎 мультитайл с множеством функций 🌊
Сеть pings, отображает онлайн-хосты в этой сети с их локальным IP-адресом и MAC-адресом
Он не требует редактирования. Требуется разрешение root для запуска.
GOOGLE_DNS="8.8.8.8"
ONLINE_INTERFACE=$(ip route get "${GOOGLE_DNS}" | awk -F 'dev ' 'NR == 1 {split($2, 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($0) ~ /reachable|stale|delay|probe/{printf ("%5s\t%s\n", $1, $5)}' | \
sort --version-sort --unique