12

オープン/アドホック/wep/wpa2 ネットワークを処理する wlan マネージャー スクリプトを作成しました。今、iw wlan0 スキャン出力を解析して、スクリプトに優れたスキャン機能を追加しようとしています。私の目標は、次のような出力を得ることです:

SSID        channel     signal      encryption
wlan-ap     6           70%         wpa2-psk
test        1           55%         wep

私がすでに達成したことは、次のような出力です:

$ iw wlan0 scan | grep 'SSID\|freq\|signal\|capability' | tac
SSID: Koti783
signal: -82.00 dBm
capability: ESS Privacy ShortPreamble SpectrumMgmt ShortSlotTime (0x0531)
freq: 2437

私は bash/sed/awk を研究しようとしていますが、私が試みていることを達成する方法をまだ見つけていません。それで、それを達成するための良い方法は何ですか?

4

7 に答える 7

8

一般に、プログラムの複雑な出力を人間が読むことを意図して解析しようとするのは悪い習慣です (機械が解析するのではなく)。

たとえば、iwシステムの言語設定や のバージョンによって の出力が変わる可能性がありiw、開発マシンでのみ機能する「マネージャー」が残ります。

代わりに、 を使用して情報を取得するのと同じインターフェースをiw使用できます: ライブラリ バックエンドlibnl

libiwライブラリを使用するwireless-tools( iwconfigiwlist、...) も参照してください。

于 2013-07-23T12:39:15.487 に答える
5

以下は、Bash 内部のみを使用し、サブシェルを 1 つだけ生成する単純な Bash 関数です。

#!/bin/bash 
function iwScan() {
   # disable globbing to avoid surprises
   set -o noglob
   # make temporary variables local to our function
   local AP S
   # read stdin of the function into AP variable
   while read -r AP; do
     ## print lines only containing needed fields
     [[ "${AP//'SSID: '*}" == '' ]] && printf '%b' "${AP/'SSID: '}\n"
     [[ "${AP//'signal: '*}" == '' ]] && ( S=( ${AP/'signal: '} ); printf '%b' "${S[0]},";)
   done
   set +o noglob
}

iwScan <<< "$(iw wlan0 scan)"

出力:

-66.00,FRITZ!Box 7312
-56.00,ALICE-WLAN01
-78.00,o2-WLAN93
-78.00,EasyBox-7A2302
-62.00,dlink
-74.00,EasyBox-59DF56
-76.00,BELAYS_Network
-82.00,o2-WLAN20
-82.00,BPPvM

while read -r AP while-loop に必要なフィルターを追加することで、関数を簡単に変更して追加のフィールドを提供できます。

[[ "${AP//'last seen: '*}" == '' ]] && ( S=( ${AP/'last seen: '} ); printf '%b' "${S[0]},";)

出力:

-64.00,1000,FRITZ!Box 7312
-54.00,492,ALICE-WLAN01
-76.00,2588,o2-WLAN93
-78.00,652,LN8-Gast
-72.00,2916,WHITE-BOX
-66.00,288,ALICE-WLAN
-78.00,800,EasyBox-59DF56
-80.00,720,EasyBox-7A2302
-84.00,596,ALICE-WLAN08
于 2014-11-25T14:42:03.617 に答える
5

以下は、GNU awk一意の BSS ごとに SSID とチャネルを取得するためのスクリプトです。

/^BSS / {
    MAC = $2
}
/SSID/ {
    wifi[MAC]["SSID"] = $2
}
/primary channel/ {
    wifi[MAC]["channel"] = $NF
}

# Insert new block here

END {
    printf "%s\t\t%s\n","SSID","channel"

    for (w in wifi) {
        printf "%s\t\t%s\n",wifi[w]["SSID"],wifi[w]["channel"]
    }
}

これまでのすべての研究を考慮すると、信号と暗号化のための新しいブロックを追加するのは簡単なはずです。

スクリプトを次のようなファイルに保存し、次のwifi.awkように実行します。

$ sudo iw wlan0 scan | awk -f wifi.awk

出力は、要求されたフォーマットになります。

SSID        channel
wlan-ap     6
test        1
于 2013-07-23T12:45:22.313 に答える
2

私はopenwrtにそのようなソリューションを使用しています:

wlan_scan.sh

#!/bin/sh
sudo iw dev wlan0 scan | awk -f wlan_scan.awk | sort

wlan_scan.awk

/^BSS/ {
    mac = gensub ( /^BSS[[:space:]]*([0-9a-fA-F:]+).*?$/, "\\1", "g", $0 );
}
/^[[:space:]]*signal:/ {
    signal = gensub ( /^[[:space:]]*signal:[[:space:]]*(\-?[0-9.]+).*?$/, "\\1", "g", $0 );
}
/^[[:space:]]*SSID:/ {
    ssid = gensub ( /^[[:space:]]*SSID:[[:space:]]*([^\n]*).*?$/, "\\1", "g", $0 );
    printf ( "%s %s %s\n", signal, mac, ssid );
}

結果

-62.00 c8:64:c7:54:d9:05 a
-72.00 70:72:3c:1c:af:17 b
-81.00 78:f5:fd:be:33:cb c
于 2016-03-01T13:55:00.890 に答える