Comportamento de criação de variáveis ​​dentro da função bash

Comportamento de criação de variáveis ​​dentro da função bash

Estou usando a função abaixo para incrementar um script externo. O objetivo principal disso é apenas retornar alguns dados das saídas de teste ifconfig e ping. Estou tentando configurá-los dentro da mesma função usando variáveis, apenas para fazer alguns outros "pipes" e concatená-los novamente com outras informações. Mas eu tenho esse comportamento. Basicamente, o que estou tentando fazer é:

    > 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 você pode ver, ele retorna o número 4 para cada iteração.

Se eu apenas remover a atribuição da variável, obtenho a saída que esperava definir na variável 'a' em primeiro 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 que estou obtendo o número 4 como saída na primeira execução do código de função?
  • Como posso definir uma variável dentro da mesma função e repeti-la novamente após alguns pipelines? Isso é possível?

Atenciosamente !

Responder1

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

Por que estou obtendo o número 4 como saída na primeira execução do código de função?

Porque a=`...`e echo $asão executados em diferentes subshells/subprocessos. a=1; a=3 | echo $airá imprimir 1em qualquer shell. Não há como passar uma variável de um subshell para seu pai.

Como posso definir uma variável dentro da mesma função e repeti-la novamente após alguns pipelines? Isso é possível?

Não. A menos que você defina isso no script principal, antes do pipeline.

Responder2

Se você reestruturar a última parte do pipeline usando, sedacho que poderá conseguir o que deseja. O sedscript corresponde a toda a entrada padrão e a substitui pelo valor $iseguido por -e pelo terceiro campo da sua pingsaída (de stdin). Por exemplo,

$ 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

informação relacionada