Я бы предложил использовать флаг nmap для проверки ping,
$ 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
Loops
Чтобы перебрать что-то в bash, вы используете for
:
$ for thingy in 1 2 3; do echo $thingy; done
1
2
3
Pinging
Далее, ping. Команда ping немного отличается в зависимости от операционной системы, разных дистрибутивов / версий (в настоящее время я использую OS X)
По умолчанию (опять же, в версии ping
для OS X) он будет пропинговать до прерывания, что не будет работать для этого, поэтому 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 завершится с кодом завершения 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
$
Сценарий
Итак, чтобы объединить все это ..
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 - первый пример» объясняет, как использовать модуль потоков Python для написания многопоточного ping'ера. Хотя в этот момент я бы еще раз предложил использовать nmap -sn
..