0
Desafiooooooo

Solved 6 Respuestas 30 Views
Alguien se anima a simplificar mi UserParam?

UserParameter=gwfibertime,ping -t2 -c1 `ifconfig re0 | awk '/inet\ / {print $2}' | awk -F "." '{print $1"."$2"."$3".1"}'` | awk -F "time=" '/64\ bytes\ from/ {print$2}' | awk '{print $1}' || echo "0"

Es para medir tiempo de respuesta del gw de una conexion de fibertel con ip dinamico.

SO: FreeBSD

Saludos

6 Respuestas

0
Mejor respuesta

 

 

ping -c1 -t2 -q `ifconfig re0 | sed -En "s/.*inet ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p"`.1 | grep ^rtt| cut -d"/" -f6

Desglosado:

`ifconfig re0 | sed -En "s/.*inet ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p"`

Saco los primeros 3 octetos de la IP,trate de usar otra forma mas compacta de RegEx, pero no me tomaba bien el grupo de captura, asi que lo deje asi, mas largo, luego:

ping -c1 -t2 -q `ifconfig re0 | sed -En "s/.*inet ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p"`.1

Le agrego el .1 y tiro el ping, con -q para que solo me de el header y el resumen, quedando la salida como:

PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.770/1.770/1.770/0.000 ms

El grep ^rtt  me da solo la ultima linea:

rtt min/avg/max/mdev = 1.770/1.770/1.770/0.000 ms

Y el cut -d"/" -f5 me da la quinta columna usando como separador el /, o sea:

rtt min/avg/max/mdev = 1.770/1.770/1.770/0.000 ms
                             ^^^^^ ---> Este numero.

Lo probe en linux, fijate en *BSD capaz que hay algun separador distinto o parametro que no es igual.
Si bsd no tiene cut podes usar sed, pero eso te lo dejo para que lo resuelvas vos ;)

 

 

respondido por qlixed (10,630 puntos) Jul 23, 2015
seleccionada por edux Ago 30, 2015
6Comentarios
comentado por qlixed (10,630 puntos) Jul 23, 2015
Me olvida: MUERTE A AWK.
comentado por luigibalzani (10,530 puntos) Jul 23, 2015
Andubo! con unos minimos cambios:

ping -c1 -t2 -q `ifconfig re0 | sed -En "s/.*inet ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p"`.1 | grep ^round-trip | cut -d"/" -f6 || echo "0"

y unos cuantos caracteres mas corto que el mio!

En este caso cut+sed le ganaron a AWK.... pero AWK sigue siendo mejor :-P

Saludos!
comentado por qlixed (10,630 puntos) Jul 23, 2015
Mas corto:

ping -c1 -t2 -q `ifconfig re0 | sed -En "s/.*inet (([0-9]{1,3}\.){3}).*/\1/p"`.1 | grep ^round | cut -d"/" -f6 || echo "0"
comentado por luigibalzani (10,530 puntos) Jul 27, 2015
Al final quedo un mix entre sed y awk:

ping -c1 -t2 -q `ifconfig re0 | sed -En "s/inet (([0-9]{1,3}\.){3}).*/\1/p"`1 | awk -F \/ '/trip/{print $6}' || echo 0
comentado por luigibalzani (10,530 puntos) Jul 27, 2015
Para que quede mas groso ahora deberia medir cual de todos consume menos recursos...
comentado por qlixed (10,630 puntos) Jul 27, 2015
En linux, con systemtap, usando https://sourceware.org/systemtap/examples/memory/glibc-malloc.stp

Tu script original:

$ stap -v ./glibc-malloc.stp -c "bash -c \"ping -t2 -c1 `ifconfig wlp3s0 | awk '/inet\ / {print $2}' | awk -F \".\" '{print $1\".\"$2\".\"$3\".1\"}'` | awk -F \"time=\" '/64\ bytes\ from/ {print$2}' | awk '{print $1}' || echo \"0\"\""
Pass 1: parsed user script and 181 library script(s) using 639240virt/455456res/6584shr/454180data kb, in 1530usr/90sys/1630real ms.
Pass 2: analyzed script: 27 probe(s), 3 function(s), 3 embed(s), 5 global(s) using 658676virt/476524res/8180shr/473616data kb, in 170usr/60sys/227real ms.
Pass 3: using cached /home/qlixed/.systemtap/cache/08/stap_08c5502ae2ab502b32061deddda46376_10873.c
Pass 4: using cached /home/qlixed/.systemtap/cache/08/stap_08c5502ae2ab502b32061deddda46376_10873.ko
Pass 5: starting run.
64 bytes from 10.216.121.1: icmp_seq=1 ttl=64 time=118 ms
malloc information for pid 16323
Contention:
Active arenas:
Allocated heaps:
Total sbrk: 540672 bytes
Mmap threshold in the end: 128 kb
Pass 5: run completed in 0usr/30sys/472real ms.

El script mixeado:

$ stap -v ./glibc-malloc.stp -c "bash -c 'ping -c1 -t2 -q `ifconfig wlp3s0 | sed -En 's/inet (([0-9]{1,3}\.){3}).*/\1/p'`1 | awk -F \/ \"/trip/{print $6}\" || echo '0''"
Pass 1: parsed user script and 181 library script(s) using 639236virt/455468res/6600shr/454176data kb, in 1510usr/90sys/1605real ms.
Pass 2: analyzed script: 27 probe(s), 3 function(s), 3 embed(s), 5 global(s) using 658672virt/476508res/8168shr/473612data kb, in 170usr/50sys/225real ms.
Pass 3: using cached /home/qlixed/.systemtap/cache/08/stap_08c5502ae2ab502b32061deddda46376_10873.c
Pass 4: using cached /home/qlixed/.systemtap/cache/08/stap_08c5502ae2ab502b32061deddda46376_10873.ko
Pass 5: starting run.
malloc information for pid 16259
Contention:
Active arenas:
Allocated heaps:
Total sbrk: 405504 bytes
Mmap threshold in the end: 128 kb
Pass 5: run completed in 0usr/40sys/358real ms.

Comparando:
Memoria: 540672 bytes - 405504 bytes = 135,168 bytes menos (-25%)
Tiempos: 0usr/30sys/472real ms. - 0usr/40sys/358real ms. = 0usr/+10sys(+33%)/-114(-24,15%)
Tiempos totales = 502 ms - 398 ms = 104 ms (-20,7%)

En BSD deberías tener unos valores aproximadamente iguales.
0

Respuesta medio ladri, creo que se podría reemplazar el awk -F "."  por awk -F \.

 

Pero es muy ladri jajajajaja

respondido por ikarudelabasto (3,220 puntos) Jul 23, 2015
1Comentarios
comentado por luigibalzani (10,530 puntos) Jul 23, 2015
jaja, por lo menos me ahorro un caracter
0
alternativa:

ping -t2 -c1 `ip r | grep re0.*link | rev | awk '{print $1}' | rev` | grep time | cut -d= -f4 | head -1
respondido por OSiUX (540 puntos) Jul 25, 2015
2Comentarios
comentado por luigibalzani (10,530 puntos) Jul 27, 2015
En mi linux funciono con estos cambios:

ping -t2 -c1 `ip r | grep eth0.*link | rev | awk '{print $3}' | rev` | grep time | cut -d= -f4 | head -1

En el FreeBSD no tengo el comando ip :-(
comentado por OSiUX Jul 27, 2015
mira vos, pensé que *ip route* era un standard :(

bueno, otra manera:

ping -t2 -c1 `netstat -ie | grep "inet addr:[0-9\.]+" | tr : ' ' | awk '{print $3}' | head -1` | grep time | cut -d= -f4 | head -1
0
UserParameter=gwfibertime[*],ping -c1 -t2 -q `ip r | perl -ne 'if(m/default via (\S+) dev $1/) {print $$1}'` 2>/dev/null | perl -ne 'if(m/rtt.*\/(\d+\.\d+)\//) {$RTT=$$1} END {if(defined $RTT) {print "$RTT\n"} else {print "0\n"} }'

al user param le mandas como parametro el "ethX" y no dependes que el gw sea siempre .1

la linea de comando en limpio seria: ping -c1 -t2 -q `ip r | perl -ne 'if(m/default via (\S+) dev eth0/) {print $1}'` 2>/dev/null | perl -ne 'if(m/rtt.*\/(\d+\.\d+)\//) {$RTT=$1} END {if(defined $RTT) {print "$RTT\n"} else {print "0\n"} }'
respondido por int21h (380 puntos) Jul 27, 2015
4Comentarios
comentado por luigibalzani (10,530 puntos) Jul 27, 2015
Tiene dos problemas, uno es que el comando ip no esta en FreeBSD y el otro es que el gateway de fibertel no es el default gw.
comentado por int21h (380 puntos) Jul 27, 2015
lo del ip r facil, netstat y listo. Fiber no tiene default gw? y como sale a todo lo que no tiene ruta especifica? me copias un netstat-nr ?
comentado por luigibalzani (10,530 puntos) Jul 27, 2015
Son dos conexiones, iplan y fiber, la de fiber se queda en standby sin gw hasta que tiene que entrar en accion y se setea como default gw, hasta ese momento no aparece el gw en el netstat -nr. Por eso lo de construir el gw cambiando el ultimo octeto por 1.
comentado por int21h (380 puntos) Jul 27, 2015
Complicado, si llegara a dar otro gw a .1 se complica.
0
Aca hay otro mas:

Linux:

ping -c1 -t2 -q `ifconfig eth0 | sed -En "s/inet\ addr:(([0-9]{1,3}\.){3}).*/\1/p"`253 | tail -1 | perl -ne '(/rtt.*=\ ([0-9\.]{1,7})\/.*/ && print "$1\n") || print "0\n"'

FreeBSD:

ping -c1 -t2 -q `ifconfig re0 | sed -En "s/inet\ (([0-9]{1,3}\.){3}).*/\1/p"`253 | tail -1 | perl -ne '(/rtt.*=\ ([0-9\.]{1,7})\/.*/ && print "$1\n") || print "0\n"'
respondido por luigibalzani (10,530 puntos) Jul 27, 2015
2Comentarios
comentado por int21h (380 puntos) Jul 27, 2015
se pueden cambiar estos dos comandos (tail | perl)
tail -1 | perl -ne '(/rtt.*=\ ([0-9\.]{1,7})\/.*/ && print "$1\n") || print "0\n"'

por 1 solo (perl)
perl -ne 'if(m/rtt.*\/(\d+\.\d+)\//) {$RTT=$1} END {if(defined $RTT) {print "$RTT\n"} else {print "0\n"} }'

parece largo pero es mucho mas rapida la repuesta,
comentado por luigibalzani (10,530 puntos) Jul 27, 2015
Aca tengo un hecho con perl tambien:

ping -c1 -t2 -q `ifconfig eth0 | sed -En "s/inet\ addr:(([0-9]{1,3}\.){3}).*/\1/p"`1 | perl -ne 'BEGIN{$a=0} {(/rtt.*=\ ([0-9\.]{1,7})\/.*/ && ($a=$1))} END{print "$a\n"}'
0

Solución:

UserParameter=gwfibertime,ping -c1 -t2 -q `ifconfig re0 | sed -n 's/^.*inet:\([^ ]*\).*$/\1/p;'` | sed -n 's,^rtt.*=[^/]*/\([^/]*\)/.*$,\1,p; t; ${ s/^.*$/0/p; };'

Uso dos "sed" one-liners, ambos con la opción "-n" para controlar qué quiero imprimir:

  1. Filtro la salida de "ifconfig": sólo muestro los caracteres que no sean espacios en blanco de la barra espaciadora (" ") encontrados luego de la cadena "inet:". Eso me da la dirección IP. Lo que está antes y después de ese texto en la línea debo descartarlo; para ello, agrego al principio "^.*" y al final ".*$".
  2. Filtro la salida de "ping": si encuentro una cadena que comience con "rtt", entonces recupero de esa línea solamente los caracteres que no sean "/" luego de la primera "/" después del "="; al resultado lo imprimo con "p". Si la expresión anterior hizo un reemplazo exitoso, salto al final del script con el comando "t" para terminar. En otro caso, voy a la última línea y reemplazo todo por un "0" e imprimo eso. Lo de ir a la última línea es sólo una convención, lo único que me interesa allí es asegurarme de que hago eso sólo una vez para que no me tire un "0" por cada línea. Podría haber elegido la primera línea también o cualquier otra, siempre que esté totalmente seguro de que habrá al menos una línea.

Siempre prefiero "iproute2" antes que "ifconfig", pero, siendo que estás en BSD, esto no es una opción. Sin embargo, aquí va el "sed" one-liner para el comando "ip":

ip -o a l dev re0 | sed -n 's/^.*inet \([^/]\+\)\/.*$/\1/p'

Además, como "iproute2" te lista todas las direcciones IP de una interfaz apropiadamente como una lista con sus respectivas etiquetas (tal como es la estructura de datos en Linux, no sé en BSD), tal vez te convenga agregar un "| head -n 1" o "| tail -n 1". Mejor aún sería conocer la etiqueta y agregarla al match de "ip". Por ejempo:

ip -o a l dev re0 label re0:1 | sed -n 's/^.*inet \([^/]\+\)\/.*$/\1/p'

EDITADO:

Escribí las expresiones regulares basándome en la salida de "ifconfig" en Linux. Según la salida de este comando en BSD, cortesía del comentario de luigibalzani, el UserParameter debería ser:

UserParameter=gwfibertime,ping -c1 -t2 -q `ifconfig re0 | sed -n 's/^.*inet \([^ ]*\).*$/\1/p;'` | sed -n 's,^rtt.*=[^/]*/\([^/]*\)/.*$,\1,p; t; ${ s/^.*$/0/p; };'

El cambio está en sustituir ":" por un espacio en blanco regular (" ") luego de "inet".

respondido por diegom (390 puntos) Jul 28, 2015
editado por diegom Jul 30, 2015
1Comentarios
comentado por luigibalzani (10,530 puntos) Jul 28, 2015
En FreeBSD no funciona porque no imprime nada entre (), habria que hacer algunos cambios en la regex. Esta es la salida del ifconfig:

# ifconfig re0                                                                                                                                    
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>                                                                
        ether x:xx:xx:xx:xx:xx                                                                                                                             
        inet6 fe80::208:54ff:feaa:db41%re0 prefixlen 64 scopeid 0x2
        inet xxx.xxx.xxx.xxx netmask 0xffffff00 broadcast 255.255.255.255
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active

Igualmente yo no conocia que podia hacer control de flujo con t asi que gracias!
...