IPアドレスを使用してarpテーブルからMACアドレスを取得したい。現在、私はこのコマンドを使用しています
arp -a $ipAddress | awk '{print $4}'
このコマンドは、私が望むものを印刷します。しかし、私はそれに慣れていません。これを行うための組み込みの方法またはより安定した方法があるのではないかと思います。
/proc/net/arp
次を使用してファイルを解析できますawk
。
awk "/^${ipAddress//./\.}\>/"' { print $4 }' /proc/net/arp
しかし、それがより単純かどうかはわかりません (ただし、1 つのフォークとサブシェルを節約できます)。
100% bash ソリューションが必要な場合:
while read ip _ _ mac _; do
[[ "$ip" == "$ipAddress" ]] && break
done < /proc/net/arp
echo "$mac"
ええと、実際に ARP プロトコル ( ATM マシンや PIN 番号のように冗長であることはわかっています) 自体を使用して情報を取得するプログラム (C 言語など) を作成することもできますが、それは、シンプルなパイプライン。
不必要な労力が発生する可能性があるため、快適さのレベルをもう少し批判的に調べる必要があるかもしれません:-)
Linux ARP カーネル モジュールのマンページには、ARP テーブルを操作または読み取るためのいくつかの方法がリストされていますが、ioctl
おそらく最も簡単な方法です。
の出力arp -a
はロケールに依存します (つまり、システム言語によって変化します)。したがって、少なくともデフォルトのロケールに強制することをお勧めします。
LC_ALL=C arp -a $ipAddress | awk '{print $4}'
ただし、出力arp -a
が解析されることを意図していないという懸念を共有しています。プログラムが Linux システムに制限されている場合、別のオプションはファイルを解析することです/proc/net/arp
。このファイルはカーネルによってエクスポートされ、arp 自体が解析して情報を取得します。このファイルの形式は、マンページ proc(5) で説明されています。 を参照してくださいman 5 proc
。これは、awk を使用して簡単に実行できます。
awk '$1==IPADDRESS {print $4}' /proc/net/arp
PIPE の更新、削除
sed -nr 's/^'${ipAddress//./\.}'.*(([0-9A-Za-z]{2}:){5}[0-9A-Za-z]{2}).*$/\1/p' /proc/net/arp
非固定カラムのソリューション;
arp -a $ipAddress | sed -n 's/^.*\(\([0-9A-Z]\{2\}:\)\{5\}[0-9A-Z]\{2\}\).*$/\1/p'
説明
^.*
^
- 文字列の先頭に任意の文字が続くものと一致します.*
。[0-9A-Z]\{2\}:
- 英数字の 2 回の後にコロンが続く任意の文字に一致します。\([0-9A-Z]\{2\}:\)\{5\}
( )
- 5回の間でパターンを一致させます。[0-9A-Z]\{2\}
- 数字英数字の任意の文字を 2 回一致させます。.*$
.*
-文字列の最後まで、任意の文字に 0 回以上一致します$
。\1/p
- キャプチャ パターン 1 を返す /p
一致を出力します。これは、列番号が常に4であると想定していない awk + sed ソリューションです。
#!/bin/bash
cat /proc/net/arp |\
# remove space from column headers
sed 's/\([^ ]\)[ ]\([^ ]\)/\1_\2/g' |\
# find HW_address column number and/or print that column
awk '{
if ( !column ) {
for (i = 1; i <= NF; i++ ) {
if ( $i ~ /HW_address/ ) { column=i }
};
print $column
}
else {
print $column
}
}'
列名が「HWアドレス」であるなど、ここにはまだ脆弱な仮定があります。
コマンドを使用して、特定の IP アドレスの MAC を明示的にクエリすることを好みarping
ます (これにより、ローカル ARP キャッシュも更新されます)。
arping -c 1 192.168.2.24 | grep -Eo "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]"
同じ IP アドレスを使用している 2 つ以上のホストが存在するかどうかを確認したり (-D オプションを追加)、ローカル VLAN で使用されている現在の IP アドレスを次のような単純なスクリプトで確認したりするのに非常に便利です。
for i in $(seq 1 254); do
IP="192.168.5.$i"
MAC=$(arping -c 1 $IP | grep -Eo "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]")
if [ "$MAC" ] ; then
echo "$IP $MAC"
fi
done
arping
この方法ではローカル ホストの IP アドレスを検出できないことに注意してください(ただし、スクリプトにチェックを追加して、範囲内に存在するかどうかを表示できます)。
arping
オプションと出力がわずかに異なるいくつかのバージョンの が存在します。Linux Ubuntu では、パッケージiputils-arpingに 1 つ、パッケージarpingにもう1 つ存在します。
注: 問題ではなく質問に答えるには、フィルタリング時に/proc/net/arp
、式をスペースで終了するなど、完全一致を保証する正規表現を使用する必要があります (そうしないと、この例では、存在する場合は 2.240-2.249 アドレスも表示されます)。
ipaddress="192.168.2.24"
grep "^${ipaddress} " /proc/net/arp | grep -Eo "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]")