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
と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
は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が起動しました!"
もう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出力を確認する必要がないので、/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
を使用することをお勧めします。
現実の世界では、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
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
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
を含むディストリビューションは知りませんが、ほとんどのディストリビューションではパッケージマネージャーから入手できます。
また、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
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,\),,
最後のオクテットのみを変更するように制限している場合は、このスクリプトで変更する必要があります。それを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
他のポスターが指摘したように、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
一部のマシンは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
_
ルートofcの場合、Sudoは必要ありません。
10.0.0.14
_:テストするIP-c1
_:1つのリクエストのみを送信します。&
_:「待ちたくない」キャラクターこれは、サブプロセスでコマンドが終了するのを待たずに(スレッドのように)コマンドを起動する可能性を与える、本当に便利なキャラクターです。
for
ループは、255個のIPアドレスすべてを取得するためのものです。 seq
コマンドを使用して、すべての数値をリストします。wait
:リクエストを開始した後、返信があるかどうかを確認します。そのためには、ループの後にwait
を配置します。 wait
は、他の言語の関数join()
のように見えます。()
_:すべての出力をテキストとして解釈するために括弧があり、grep
に渡すことができますgrep
:返信のみを表示します。 2番目の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]+'
_
古い質問ではありますが、それは依然として重要であると思われます(少なくとも、私がこれに対処するには十分に重要です)。私のスクリプトも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
#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
ホストのリストを提供する場合は、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
次の(悪)コードは、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秒かかります...
まあ、これは私のスクリプトの一部です。
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
#!/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