Как я могу написать linux bash script, который сообщает мне, какие компьютеры включены в моей локальной сети?
Это помогло бы, если бы я мог указать его как входной диапазон IP-адресов.
Как я могу написать linux bash script, который сообщает мне, какие компьютеры включены в моей локальной сети?
Это помогло бы, если бы я мог указать его как входной диапазон IP-адресов.
Я бы предложил использовать флаг 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
.. и объяснение каждого бит указанной команды:
Вы можете использовать синтаксис {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. Команда 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
Затем нам нужно знать, отвечает ли машина или нет.
Мы можем использовать оператор &&
для запуска команды, если первое выполняется успешно, например:
$ 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, поэтому мы можем перенаправить 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
$
Итак, чтобы все это совместить..
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
..
В реальном мире вы можете использовать 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
Я получу ответ со всех компьютеров в этой сети, которые не блокировали свой порт 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
Существует также 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]\+\).*/\1/p' | sort | uniq
Конечно, вам нужно будет изменить широковещательный адрес на адрес вашей сети.
Просто для удовольствия, здесь альтернативный
#!/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,\),,
Если вы ограничиваете себя только тем, что изменили последний октет, этот 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
Как отмечали другие плакаты, 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 $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
Хотя старый вопрос, он все еще кажется важным (по крайней мере, достаточно важным для меня, чтобы иметь дело с этим). Мой 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.
Если вы хотите предоставить список хостов, это можно сделать с помощью 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
Некоторые машины не отвечают на запросы (например, брандмауэры).
Если вам нужна только локальная сеть, вы можете использовать эту команду:
(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
Плохой частью моего решения является то, что он печатает все результаты в конце. Это потому, что 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
Следующий (злой) код работает больше, чем 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 секунд...
Ну, это часть моего 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