Linux/Unix Shell Scripting - Ayuda con salida del comando "iwlist wlan0 scan"

 
Vista:
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 23/05/2017 16:59:34
Saludos a todos, espero puedan ayudarme.
Tengo las siguientes líneas:

1
2
3
4
5
6
7
8
9
10
wifislax ~ # mac_ap="76:BA:DB:12:37:55"
wifislax ~ # a=`sudo iwlist wlan0 scan | egrep -i 'ESSID|Address:|Channel:'`
wifislax ~ # echo "$a"
          Cell 01 - Address: 76:BA:DB:12:37:55
                    Channel:6
                    ESSID:"BLU DASH MUSIC JR"
          Cell 02 - Address: 3A:2D:D1:FE:99:97
                    Channel:1
                    ESSID:"DIRECT-Ns-1xAAAAbGlzYW5kcml0YTIx"
wifislax ~ #

Hasta quí todo bien. Pero...
De la salida del comando "iwlist" almacenada en la variable "$a", necesito extraer en dos variables distintas los datos correspondientes a la MAC almacenada en la variable "$mac_ap".
Ejemplo:
Para la mac "76:BA:DB:12:37:55" (la cual se encuentra asignada actualmente a la variable $mac_ap) necesito algo como lo siguiente:

$canal=6
$nombre="BLU DASH MUSIC JR"

Debemos darnos cuenta que la MAC que se busca puede estar lo mismo al inicio , en el medio, o en cualquier posición dentro de la salida de iwlist. Comento esto porque entre tanto invento que hice logré que me diera lo que quiero, pero solo daba bien si se encontraba al inicio (muy mal )

Talvés sea simple realizar lo que quiero pero les confieso que soy bastante nuevo en este lenguaje, que aunque tenga claro el algoritmo a seguir para resolver el problema y terminar el script general, me falta mucho por aprender.
Espero la ayuda de todos y gracias por al menos leer estas líneas.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 24/05/2017 03:54:35
De verdad nadie me puede ayudar?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de kip
Val: 64
Plata
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por kip (17 intervenciones) el 24/05/2017 05:36:28
Hola, hice algo rapido y un poco engorroso a ver si te sirve con awk, simule tu contenido de $a con un cat a un archivo en el cual pegue el valor que colocaste arriba, aqui el codigo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a=$(cat text)
mac="76:BA:DB:12:37:5"
info=$(echo $a | awk -v adrs=$mac '{
    for(i=1;i<=NF;i++) {
        if (index($i, adrs)) {
            a=i+1
            while(1) {
                if (index($a, "Cell")) {
                   break
                }
                print $a
                a++
           }
        }
    }
}')
canal=$(echo $info | grep -oP 'Channel:\K[0-9]+')
nombre=$(echo $info | grep -oP '\"\K[A-Za-z\s]+')
 
echo $canal
echo $nombre

Me muestra:
1
2
6
BLU DASH MUSIC JR

Intenta probarlo y cuentanos si te salta algun error, ok ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 24/05/2017 17:44:31
Gracias kip, lo probaré esta noche cuando llegue a casa y te digo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 24/05/2017 23:48:49
Ya resolví el problema.
Tomé la idea general del código que me pusiste. Aquí lo dejo por si a alguien le hace falta (tiene los comentarios necesarios para que todos lo entiendan. Tiene además unos "echo" comentados que muestran en todo momento la marcha del proceso). Cualquier sugerencia para hacerlo mejor se agradece:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/bash
 
#Direccion MAC que vamos a monitorear
mac_ap="76:BA:DB:12:37:55"
 
#Escanemos las redes y almecenamos en la variable "$a"
a=`sudo iwlist wlan0 scan | egrep -i 'ESSID|Address:|Channel:'`
 
#echo "$a"
 
#Esto es un ejemplo del contenido de la variable $a
#a='          Cell 01 - Address: 76:BA:DB:12:37:00
#                    Channel:5
#                    ESSID:"BLU DASH MUSIC JR"
#             Cell 02 - Address: 76:BA:DB:12:37:55
#                    Channel:65
#                    ESSID:"BLU DASH MUSIC JR"'
 
 
 
#-----------------------OBTENEMOS LOS DATOS----------------------------------------
#Guardamos la variable $a en un archivo para procesarla
echo "$a" > 'tmp.txt'
i=1
while read line #Leemos el archivo linea a linea
do
 
   tmp_line="$line"
   #echo $i "$tmp_line"
 
    #Comprobamos si $mac_ap existe en la linea actual   
    if [[ "$tmp_line" == *"$mac_ap"* ]]
    then
      #Si la mac se encuentra en la linea actual...
      #echo "La MAC se encuentra en la linea $i";
      #Extraemos el canal de la proxima linea
      canal=$(head -$((i+1)) 'tmp.txt' | tail -1 | grep -oP 'Channel:\K[0-9]+')
      #Salimos del ciclo
      break
    fi
 
   i=$((i+1))
done < 'tmp.txt'
 
 
#----------------------------------------------
#Imprimimos los datos obtenidos
echo "MAC: $mac_ap Canal: $canal"
#FIN

Espero me den su opinión.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Tom (331 intervenciones) el 25/05/2017 08:31:13
(No lo he probado)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh
 
MAC_AP="76:BA:DB:12:37:55"
 
FOUND=0
CHANNEL=""
 
sudo iwlist wlan0 scan | egrep -i 'ESSID|Address:|Channel:' | while read LINE
do
	if [[ "$LINE" == ".*Address: $MAC_AP" ]]
	then
		FOUND=1
	else if [[ "$LINE" == ".*Channel:.*" && $FOUND ]]
	then
		CHANNEL=$(expr "$LINE" : '.*Channel:\(.*\)')
		break;
	fi
done
 
echo $MAC_AP : $CHANNEL
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 25/05/2017 16:11:09
Saludos Tom, ayúdame a entender lo que estas haciendo en las siguientes líneas:

1
2
3
4
5
6
7
8
9
if [[ "$LINE" == ".*Address: $MAC_AP" ]]
	then
	FOUND=1
else if [[ "$LINE" == ".*Channel:.*" && $FOUND ]]
	then
		CHANNEL=$(expr "$LINE" : '.*Channel:\(.*\)')
		break;
	fi
fi #Este faltaba

Corrígeme si me equivoco:
1. Compruebas que en la línea actual se encuentre la MAC que andamos buscando.
2. Asignas 1 a la variable FOUND indicando que ya encontraste la línea que contiene el canal.
3. En caso de que en la línea actual no se encuentre la MAC comprobamos si correspone a una línea de canal y si hemos encontrado la MAC en la línea anterior.
4. En caso de que todo lo anterior sea verdadero, extraemos el canal.

Si esto es lo que has intentado hacer está todo bien algorítmicamente pero.... No se por qué no funciona.

El ciclo que realizas es más eficiente (funciona a la perfección) que la solución anterior puesto que no escribimos en disco.
El único problema ahora es la extración de los datos.

Pudiéramos utilizar la metodología anterior tratando de leer la próxima línea después de encontrar la correspondiente a la MAC... PERO AHÍ ME PIERDO.

Alguna sugerencia.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Tom (331 intervenciones) el 25/05/2017 20:12:05
No funciona porque está hecho deprisa y "de memoria" :)
En principio hay errores de sintaxis.
No puedo probar iwlist pero he hecho algo parecido que sí funciona:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh
 
MAC_AP="76:BA:DB:12:37:55"
 
FOUND=0
CHAN=9999
 
#sudo iwlist wlan0 scan | egrep -i 'ESSID|Address:|Channel:' | while read LINE
sudo cat /tmp/test.txt | egrep -i 'ESSID|Address:|Channel:' | while read LINE
do
	if [[ "$LINE" == *Address:\ $MAC_AP ]]
	then
		FOUND=1
	elif [[ "$LINE" == *Channel:* ]]
	then
		CHAN=$(expr "$LINE" : '.*Channel:\(.*\)')
		echo $MAC_AP : $CHAN
		break
	fi
done

Esto genera otro problemilla, si quieres usar los datos en la misma shell y es que al asignar la variable CHAN dentro de una subshell (es inevitable, por el uso de sudo) fuera de ella no se ve el cambio.
Prueba a repetir, después del último done, esto:

echo $MAC_AP : $CHAN

Y verás que este último echo _no_ muestra el valor correcto de $CHAN

Por supuesto también hay soluciones para eso, pondré una a continuación
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Tom (331 intervenciones) el 25/05/2017 20:42:22
No me gusta demasiado, pero esta es una solución:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh
 
MAC_AP="76:BA:DB:12:37:55"
 
FOUND=0
CHANNEL=0
 
#sudo iwlist wlan0 scan | egrep -i 'ESSID|Address:|Channel:' > /tmp/test.txt
read IGNORE CHANNEL <<< $(
egrep -i 'ESSID|Address:|Channel:' /tmp/test.txt | while read LINE
do
	if [[ "$LINE" == *Address:\ $MAC_AP ]]
	then
		FOUND=1
	elif [[ "$LINE" == *Channel:* ]]
	then
		CHAN=$(expr "$LINE" : '.*Channel:\(.*\)')
		echo $MAC_AP $CHAN
		break
	fi
done
)
 
echo "Canal $CHANNEL para MAC $MAC_AP"

Por cierto, hay quien considera que solamente por usar el pipe (|) ya se abre una subshell ... yo creo que el problema de esta es el tener que usar sudo (de hecho, la línea "read IGNORE CHANNEL <<< no funciona bien en cuanto pones el sudo ...
Así que mejor, mezclar un poco de vuestras primeras soluciones, y almacenar la salida de sudo ... en un fichero temporal
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de kip
Val: 64
Plata
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por kip (17 intervenciones) el 25/05/2017 21:29:46
Entiendo, supongo que no quieres usar awk no?

He preparado otro codigo ademas del que te aportaron:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
a="Cell 01 - Address: 76:BA:DB:12:37:55
        Channel:6
        ESSID:\"BLU DASH MUSIC JR\"
    Cell 02 - Address: 3A:2D:D1:FE:99:97
        Channel:1
        ESSID:\"DIRECT-Ns-1xAAAAbGlzYW5kcml0YTIx\"";
 
IFS=$'\n';
array=($a);
mac="76:BA:DB:12:37:55";
found=0
info=""
 
for item in ${array[@]}
do
    if [[ "$item" == *"$mac"* ]]
    then
        found=1
    elif [ "$found" -eq "1" ]
    then
        if [[ "$item" == *"Cell"* ]]
        then
            break;
        fi
        info="$info""$item";
    fi
done
 
canal=$(echo $info | grep -oP 'Channel:\K[0-9]+')
essid=$(echo $info | grep -oP '\"\K[A-Za-z\s]+')
 
echo "MAC - $mac | CANAL - $canal | ESSID - '$essid'";

No lo he probado usando como valor de a el retorno de iwlist tal como tienes, pero puedes probar.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 26/05/2017 04:52:09
La verdad es que hemos llegado todos a +- la misma solución.
El problema de q las variables al final del ciclo no contenían valor lo resolví también con un archivo (fue la manera más rápida q encontré).
Ahora está funcionando bien con datos prederteminAdos, mañana lo voy a probrar con redes reales haber como funciona y les pongo como lo he dejado y si me da algún problema(espero q no)
No me gustaba mucho tener a escribir en cada escaneo en un archivo pero como son solamnte uno o dos números...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 12
Ha mantenido su posición en Linux/Unix Shell Scripting (en relación al último mes)
Gráfica de Linux/Unix Shell Scripting

Ayuda con salida del comando "iwlist wlan0 scan"

Publicado por Yulexis (7 intervenciones) el 26/05/2017 15:07:43
Gracias Tom y Kip. Sus soluciones funcionan perfectamente.
Aquí les dejo como lo había dejado yo (aunque ahora lo voy a cambiar un poquito):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/bin/sh
 
mac_ap="76:BA:DB:12:37:55"
 
retardo=5 #Esta variable contendra el tiempo entre cada escaneo. No lo he puesto pero al final va.
 
FOUND=0
 
#Este archivo contendra el canal.
#Lo creo ahora porque si no da un error cuando se intenta leer y no existe.
echo "0" > 'tmp_canal.txt'
 
 
#Cilco que marca el ritmo de escaneo
nada=0
echo "CONTROl-C para terminar"
while [ $nada ]
do
 
	  i=1
	  sudo iwlist wlan0 scan | egrep -i 'ESSID|Address:|Channel:' | while read linea
 
	  do
		#echo $linea
 
	      if [[ "$linea" == *"Address: $mac_ap"* ]]
	      then
		  #echo "Encontrado en la linea $i"
		  FOUND=1
 
	      else if [[ "$linea" == *"Channel:"* && $FOUND == 1 ]]
		then
		    #echo "Encontrado CANAL en la linea $i"
 
		    #echo ${linea#*'Channel:'}  
 
		    canal=$(echo `expr "$linea" : 'Channel:.*\([0-9]\)'`)
		    #echo "Canal: $canal"
 
		    canal_viejo=`cat tmp_canal.txt`
 
		    #Comprobamos si el canal actual es diferente que el canal_viejo, para ejecutar las acciones necesarias.
		    if [[ "$canal_viejo" != *"$canal"* ]]
		    then
 
			echo "Canal detectado: $canal. Ejecutando acciones..."
			echo "$canal" > 'tmp_canal.txt' # Guardamos el canal actual en el archivo
 
			# ---------- AQUI LAS ACCIONES A EJECUTAR CUANDO CAMBIA DE CANAL ----------
 
			#---------------------------------------------------------------------------------------------------------------------------
 
		    fi
 
		    break
		fi
	      fi
 
	      i=$((i+1))
	  done
 
	#Al precionar Ctnrol-C Paramos el escaneo
	trap "break" SIGINT SIGTERM
 
done #Fin del ciclo de escaneo
 
clear
echo "TERMINADO"
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar