web-dev-qa-db-ja.com

LANでどのコンピューターがオンになっているかを示すlinux bashスクリプトを作成するにはどうすればよいですか?

LANでどのコンピューターがオンになっているかを示すlinux bashスクリプトを作成するにはどうすればよいですか?

入力としてIPの範囲を指定できれば助かります。

32
Dumb Questioner

Nmapの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 -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}dir1dir2を含むsub1sub2を作成する場合にも便利です)

したがって、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を実行します。pingコマンドは、オペレーティングシステム、ディストリビューション/バージョンが異なると少し異なります(現在OS Xを使用しています)

デフォルトでは(これもOS Xバージョンのpingで)中断されるまでpingを実行しますが、これは機能しません。したがって、ping -c 1は1つのパケットのみを送信しようとします。マシンが稼働しているかどうかを判断するのに十分です。

もう1つの問題はタイムアウト値です。このバージョンのpingでは11秒のようです。-tフラグを使用して変更されています。ローカルネットワーク上のマシンが稼働しているかどうかを確認するには、1秒で十分です。

したがって、使用する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が起動しました!"

もう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出力を確認する必要がないので、/dev/nullリダイレクトを使用してstdout>にリダイレクトできます。次に例を示します。

$ 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タイムアウトフラグを1秒に設定しているため)。一度に実行できるpingコマンドは1つだけです。これを回避する明らかな方法は、スレッドを使用することです。これにより、同時コマンドを実行できますが、bashを使用する必要はありません。

"Pythonスレッド-最初の例" Pythonスレッド化モジュールを使用してマルチスレッドping'erを記述する方法を説明します。その時点で、もう一度nmap -snを使用することをお勧めします。

77
dbr

現実の世界では、nmapを使用して必要なものを取得できます。

nmap -sn 10.1.1.1-255

これにより、10.1.1.1から10.1.1.255の範囲のすべてのアドレスにpingが送信され、どのアドレスが応答するかがわかります。

もちろん、実際にこれをbashの演習として行いたい場合は、各アドレスに対してpingを実行して出力を解析できますが、それはまったく別の話です。

14
Tiberiu Ana

私のネットワークが10.10.0.0/24であると仮定して、次のようなブロードキャストアドレスでpingを実行すると

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 

したがって、たとえばawkを使用して、4番目の列を抽出する必要があります。

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オプションは、スクリプトが終了するため、pingの数を制限します。独自のIPで制限することもできます

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

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

ホストに並行してpingを実行するため、スキャンは非常に高速です。デフォルトのインストールにfpingを含むディストリビューションは知りませんが、ほとんどのディストリビューションではパッケージマネージャーから入手できます。

8
d0k

また、chburdによって指摘された「ブロードキャストアドレスのping」メソッドを使用すると、このパイプはあなたのためにトリックを行うはずです。

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

もちろん、ブロードキャストアドレスをネットワークのアドレスに変更する必要があります。

2
Can Berk Güder

楽しみのために、ここに代替手段があります


     #!/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,\),,
2
Eddy

最後のオクテットのみを変更するように制限している場合は、このスクリプトで変更する必要があります。それを1オクテットから複数オクテットに拡張する方法はかなり明白なはずです。

#! /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 
1
Vatine

他のポスターが指摘したように、nmapを使用する方法がありますが、bashでpingスキャンに相当する方法を次に示します。現在、ブロードキャストICMPに応答しないように多くのシステムが構成されているため、ブロードキャストpingは使用しません。

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
1
Don Werve

一部のマシンはpingに応答しません(ファイアウォールなど)。

ローカルネットワークのみが必要な場合は、次のコマンドを使用できます。

_(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
_

ルートofcの場合、Sudoは必要ありません。

  • _10.0.0.14_:テストするIP
  • _-c1_:1つのリクエストのみを送信します。

  1. _&_:「待ちたくない」キャラクター

これは、サブプロセスでコマンドが終了するのを待たずに(スレッドのように)コマンドを起動する可能性を与える、本当に便利なキャラクターです。


  1. forループは、255個のIPアドレスすべてを取得するためのものです。 seqコマンドを使用して、すべての数値をリストします。

  1. wait:リクエストを開始した後、返信があるかどうかを確認します。そのためには、ループの後にwaitを配置します。 waitは、他の言語の関数join()のように見えます。

  1. _()_:すべての出力をテキストとして解釈するために括弧があり、grepに渡すことができます

  1. grep:返信のみを表示します。 2番目のgrepは、IPを強調するためだけにあります。

hth

編集20150417:マキシアップデート!

私のソリューションの悪い点は、すべての結果を最後に出力することです。これは、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]+'
_
1
Boop

古い質問ではありますが、それは依然として重要であると思われます(少なくとも、私がこれに対処するには十分に重要です)。私のスクリプトもnmapに依存しているため、スキャンするインターフェイスを定義でき、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 $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

1つのコメント:このスクリプトはOSXで作成されるため、Linux環境にいくつかの変更が加えられる可能性があります。

1
d3v3l
#!/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
1
hemanth.hm

ホストのリストを提供する場合は、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スキャン-ホストがオンラインかどうかを判断するだけです

-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の範囲です

スクリプトを実行します。

./hostcheck.sh hostfile

すべての情報を含むファイルをpingscanし、オンラインのホストを使用してアップリスト(アップ)、オフラインのホストを使用してダウンリスト(ダウン)を生成します。

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
1
viniciusfcosta
1
raspi

次の(悪)コードは、nmapメソッドと同じくらい速くTWICEを超えて実行されます

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

標準のnmapで約10秒かかります

nmap -sP 192.168.1.1-254

25秒かかります...

0
Mike Redrobe

まあ、これは私のスクリプトの一部です。

ship.sh ????シンプルで便利なネットワークアドレス指定????豊富な機能を備えたマルチツール????

pingネットワーク、ローカルIPおよびMACアドレスでそのネットワーク上のオンラインホストを表示

編集する必要はありません。実行するにはルート権限が必要です。

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
0
xtonousou
#!/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
0
erik