LAN でどのコンピュータがオンになっているかを通知する Linux Bash スクリプトを作成するにはどうすればよいですか?
入力として IP アドレスの範囲を指定できると助かります。
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
..および上記のコマンドの各ビットの説明:
構文を使用して{1..10}
、数値のリストを生成できます。たとえば、..
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
mkdir {dir1,dir2}/{sub1,sub2}
(これは - がdir1
andを作成しdir2
、それぞれがsub1
andを含むようなものにも役立ちます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
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
次に、マシンが応答したかどうかを知る必要があります..
オペレーターを使用して&&
、最初のコマンドが成功した場合にコマンドを実行できます。次に例を示します。
$ 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 is up!"
もう 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 の出力を確認する必要がないため、リダイレクト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 タイムアウト フラグを 1 秒に設定しているため)。一度に 1 つの ping コマンドしか実行できません。これを回避する明白な方法は、スレッドを使用することです。これにより、並行コマンドを実行できますが、それは bash を使用する目的を超えています。
「Python スレッド - 最初の例」では、Python スレッド化モジュールを使用してマルチスレッド ping'er を作成する方法について説明していnmap -sn
ます。
現実の世界では、nmapを使用して必要なものを取得できます。
nmap -sn 10.1.1.1-255
これにより、10.1.1.1から10.1.1.255の範囲のすべてのアドレスにpingが実行され、どのアドレスが応答するかが通知されます。
もちろん、実際にこれをbashの演習として実行したい場合は、アドレスごとにpingを実行して出力を解析することもできますが、それはまったく別の話です。
私のネットワークが10.10.0.0/24であると仮定すると、次のようなブロードキャストアドレスでpingを実行すると
ping -b 10.10.0.255
このネットワーク上のICMPpingポートをブロックしなかったすべてのコンピューターから回答が得られます。
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
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
が、ほとんどのディストリビューションではパッケージマネージャーから入手できます。
楽しみのために、ここに別の方法があります
#!/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,\),,
また、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
もちろん、ブロードキャスト アドレスをネットワークのアドレスに変更する必要があります。
#!/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
一部のマシンは 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]+'
arping
ARP リクエストを送信するコマンドです。ほとんどの Linux に存在します。例:
sudo arping -c1 10.0.0.14
root ofc の場合、sudo は必要ありません。
10.0.0.14
: テストする IP-c1
: リクエストを 1 つだけ送信します。&
: 「待ちたくない」キャラクターこれは非常に便利な文字であり、サブプロセスの終了を待つことなく (スレッドのように) サブプロセスでコマンドを起動する可能性を提供します。
for
255 個の IP アドレスすべてを arping するためにここにあります。seq
コマンドを使用して、すべての番号を一覧表示します。wait
: リクエストを開始した後、返信があるかどうかを確認します。そのためにはwait
、ループの後に置きます。
他の言語wait
の関数のように見えます。join()
()
: 括弧は、すべての出力をテキストとして解釈して、grep
grep
: 返信のみが必要です。2 番目の grep は、IP を強調表示するためのものです。h番目
私のソリューションの悪い点は、最後にすべての結果を出力することです。これは、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]+'
他のポスターが指摘し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
古い質問ですが、それでも重要なようです (少なくとも、私がこれに対処するのに十分重要です)。私のスクリプトも 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 環境にいくつかの変更がある可能性があります。
#!/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
次の (悪意のある) コードは、nmap メソッドの 2 倍以上の速さで実行されます
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秒かかります...