Comportamiento de la creación de variables dentro de la función bash

Comportamiento de la creación de variables dentro de la función bash

Estoy usando la siguiente función para incrementar un script externo. El objetivo principal de esto es simplemente devolver algunos datos de ifconfig y las salidas de prueba de ping. Estoy tratando de configurarlos dentro de la misma función usando variables, solo para hacer otras "tuberías" y concatenarlas nuevamente con otra información. Pero tengo este comportamiento. Básicamente, lo que estoy tratando de hacer es:

    > for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | a=`echo $i-$(cut -d,
    -f3)` | echo $a; done  
4  
4  
4  
4

Como puede ver, devuelve el número 4 para cada iteración.

Si simplemente elimino la atribución de la variable, obtengo el resultado que esperaba establecer en la variable 'a' en primer lugar:

> for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | echo $i-$(cut -d, -f3); done
10.0.2.15- 0% packet loss
192.168.0.2- 0% packet loss
10.0.2.100- 0% packet loss
127.0.0.1- 0% packet loss
  • ¿Por qué obtengo el número 4 como resultado en la primera ejecución del código de función?
  • ¿Cómo puedo configurar una variable dentro de la misma función y repetirla nuevamente después de algunas canalizaciones? ¿Es eso posible?

Atentamente !

Respuesta1

 for i in $(...) ; do ... | a=`...` | echo $a; done

¿Por qué obtengo el número 4 como resultado en la primera ejecución del código de función?

Porque a=`...`y echo $ase ejecutan en diferentes subcapas/subprocesos. a=1; a=3 | echo $ase imprimirá 1en cualquier shell. No hay forma de pasar una variable de un subshell a su padre.

¿Cómo puedo configurar una variable dentro de la misma función y repetirla nuevamente después de algunas canalizaciones? ¿Es eso posible?

No. A menos que lo configures en el script principal, antes de la canalización.

Respuesta2

Si reestructuras la última parte del proceso usando, sedcreo que puedes conseguir lo que quieres. El sedscript coincide con toda la entrada estándar y la reemplaza con el valor $iseguido de -y el tercer campo de su pingsalida (de stdin). Por ejemplo,

$ for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f3 | cut -d: -f2); do \
    ping -c1 $i | grep packet | cut -d, -f3 | sed "s/\(.*\)/$i - \\1/"; \
done
123.145.167.189 -  0% packet loss
127.0.0.1 -  0% packet loss

información relacionada