2013-07-23 2 views
6

Я написал скрипт менеджера wlan для работы с сетями open/ad-hoc/wep/wpa2. Теперь я пытаюсь разобрать вывод iw wlan0 для получения хорошей функции сканирования для моего скрипта. Моя цель состоит в том, чтобы получить такой вывод:Parsing iw wlan0 scan output

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

Что я achived уже выводится так:

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

Я пытался изучить Баш/SED/AWK но нету нашел еще способ для достижения того, что я пытаюсь. Итак, что хорошего для этого?

+1

Ввод не предоставляет достаточной информации для достижения этого результата. – hek2mgl

+0

Обратите внимание, что на странице собственной справки iw говорится: «НЕ экранируйте этот инструмент, мы не считаем его выход стабильным». – Bryce

ответ

7

Вот мое окончательное решение, основанное на Sudo_O answer:

$1 == "BSS" { 
    MAC = $2 
    wifi[MAC]["enc"] = "Open" 
} 
$1 == "SSID:" { 
    wifi[MAC]["SSID"] = $2 
} 
$1 == "freq:" { 
    wifi[MAC]["freq"] = $NF 
} 
$1 == "signal:" { 
    wifi[MAC]["sig"] = $2 " " $3 
} 
$1 == "WPA:" { 
    wifi[MAC]["enc"] = "WPA" 
} 
$1 == "WEP:" { 
    wifi[MAC]["enc"] = "WEP" 
} 
END { 
    printf "%s\t\t%s\t%s\t\t%s\n","SSID","Frequency","Signal","Encryption" 

    for (w in wifi) { 
     printf "%s\t\t%s\t\t%s\t%s\n",wifi[w]["SSID"],wifi[w]["freq"],wifi[w]["sig"],wifi[w]["enc"] 
    } 
}' 

Выход:

$ sudo iw wlan0 scan | awk -f scan.awk 
SSID  Frequency Signal  Encryption 
netti  2437  -31.00 dBm Open 
Koti783  2437  -84.00 dBm WPA 
WLAN-AP  2462  -85.00 dBm WPA 
+1

Хорошая работа, рад, что вам удалось получить полное решение и отправить ответ всем +1. Теперь у вас достаточно репутации, вы можете +1 мое решение :) –

+1

Нет IE «WEP», поэтому ваше решение не работает для обнаружения WEP-шифрования. –

+0

Как упоминалось выше @ nicolas-marchildon, вам нужно установить gawk в Raspberry Pi, чтобы иметь возможность запускать это. – Jordan

2

В целом, это плохая практика, чтобы попытаться разобрать сложный вывод программ, предназначенных для людей, чтобы читать (а не машины для разбора).

например. вывод iw может меняться в зависимости от языковых настроек системы и/или версии iw, оставляя вас с «менеджером», который работает только на вашей машине разработки.

вместо этого вы можете использовать один и тот же интерфейс, который iw использует, чтобы получить это информация: библиотеки бэкенд libnl

вы также можете иметь взглянуть на wireless-tools (iwconfig, iwlist ...), которые используют libiw библиотека.

+0

Позвольте мне исправить. iw использует библиотеку libnl. –

+0

@AriMalinen действительно, спасибо: я обновил свой ответ соответственно –

+0

Обратите внимание, что на собственной странице справки iw говорится: «НЕ экранируйте этот инструмент, мы не считаем его выход стабильным». – Bryce

5

Вот GNU awk скрипт, чтобы вы собираетесь, что захватывает SSIDs и канал для каждого уникального ПБС:

/^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 
+0

Thats очень приятно и полезно. Спасибо. Я просто не могу узнать, как показать шифрование AP: s. –

+2

Это здорово, если вам повезло использовать gawk вместо традиционного Awk. Команда awk в OpenWrt поступает из Busybox и не поддерживает многомерные массивы. –

3

Вот простая функция Bash, которая использует исключительно 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 

Функция может быть легко изменена, чтобы обеспечить дополнительное полей, добавив необходимый фильтр во время считывания -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 
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