5

IPアドレスを使用してarpテーブルからMACアドレスを取得したい。現在、私はこのコマンドを使用しています

arp -a $ipAddress | awk '{print $4}'

このコマンドは、私が望むものを印刷します。しかし、私はそれに慣れていません。これを行うための組み込みの方法またはより安定した方法があるのではないかと思います。

4

7 に答える 7

5

/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"
于 2012-12-08T14:01:41.667 に答える
1

ええと、実際に ARP プロトコル ( ATM マシンや PIN 番号のように冗長であることはわかっています) 自体を使用して情報を取得するプログラム (C 言語など) を作成することもできますが、それは、シンプルなパイプライン。

不必要な労力が発生する可能性があるため、快適さのレベルをもう少し批判的に調べる必要があるかもしれません:-)

Linux ARP カーネル モジュールのマンページには、ARP テーブルを操作または読み取るためのいくつかの方法がリストされていますが、ioctlおそらく最も簡単な方法です。

于 2012-12-08T13:50:21.327 に答える
1

の出力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
于 2012-12-08T14:01:19.043 に答える
0

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一致を出力します。
于 2012-12-09T05:46:46.293 に答える
0

これは、列番号が常に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アドレス」であるなど、ここにはまだ脆弱な仮定があります。

于 2012-12-09T03:08:55.217 に答える
0

コマンドを使用して、特定の 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]")
于 2021-12-16T23:08:22.463 に答える