Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 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

Ответ 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: отправить только один запрос.

  1. &: символ 'I-don't-want-to-wait'

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


  1. цикл for находится здесь, чтобы задействовать все 255 IP-адресов. Он использует команду seq для отображения всех номеров.
    1. wait: после того, как мы запустили наши запросы, мы хотим узнать, есть ли ответы. Для этого просто поместите wait после цикла. wait выглядит как функция join() на других языках.
      1. (): скобки заключаются здесь в том, чтобы интерпретировать все выходы как текст, чтобы мы могли передать его grep
        1. 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