Alcance variable de Bash

Por favor, explíqueme por qué la última statement de “eco” está en blanco? Espero que se incrementó en el ciclo while a un valor de 1:

#!/bin/bash OUTPUT="name1 ip ip status" # normally output of another command with multi line output if [ -z "$OUTPUT" ] then echo "Status WARN: No messages from SMcli" exit $STATE_WARNING else echo "$OUTPUT"|while read NAME IP1 IP2 STATUS do if [ "$STATUS" != "Optimal" ] then echo "CRIT: $NAME - $STATUS" echo $((++XCODE)) else echo "OK: $NAME - $STATUS" fi done fi echo $XCODE 

Intenté usar la siguiente statement en lugar del método ++ XCODE

 XCODE=`expr $XCODE + 1` 

y tampoco se imprimirá fuera de la statement while. Creo que me falta algo sobre el scope variable aquí, pero la página de ol ‘man no me lo está mostrando.

Debido a que está conectado al bucle while, se crea un subcarte para ejecutar el ciclo while. Ahora este proceso hijo tiene su propia copia del entorno y no puede pasar ninguna variable a su padre (como en cualquier proceso de Unix).

Por lo tanto, tendrá que reestructurar para no estar metiéndose en el circuito. Alternativamente, podría ejecutar una función, por ejemplo, y repetir el valor que desea devolver desde el proceso secundario.

http://tldp.org/LDP/abs/html/subshells.html#SUBSHELL

El problema es que los procesos que se ensamblan con una tubería se ejecutan en subcapas (y, por lo tanto, tienen su propio entorno). Lo que pase dentro del while no afecta nada fuera de la tubería.

Su ejemplo específico puede resolverse reescribiendo el tubo a

 while ... do ... done <<< "$OUTPUT" 

o quizás

 while ... do ... done < <(echo "$OUTPUT") 

Esto debería funcionar también (porque echo y while están en la misma subshell):

 #!/bin/bash cat /tmp/randomFile | (while read line do LINE="$LINE $line" done && echo $LINE ) 

Una opción más:

 #!/bin/bash cat /some/file | while read line do var="abc" echo $var | xsel -i -p # redirect stdin to the X primary selection done var=$(xsel -o -p) # redirect back to stdout echo $var 

EDITAR: Aquí, xsel es un requisito (instalarlo). Alternativamente, puede usar xclip: xclip -i -selection clipboard lugar de xsel -i -p

  #!/bin/bash OUTPUT="name1 ip ip status" +export XCODE=0; if [ -z "$OUTPUT" ] ---- echo "CRIT: $NAME - $STATUS" - echo $((++XCODE)) + export XCODE=$(( $XCODE + 1 )) else echo $XCODE 

ver si esos cambios ayudan

Otra opción es generar los resultados en un archivo de la subcapa y luego leerlo en el shell principal. algo como

 #!/bin/bash EXPORTFILE=/tmp/exportfile${RANDOM} cat /tmp/randomFile | while read line do LINE="$LINE $line" echo $LINE > $EXPORTFILE done LINE=$(cat $EXPORTFILE) 

Entendí esto cuando estaba haciendo mi propio pequeño du:

 ls -l | sed '/total/d ; s/ */\t/g' | cut -f 5 | ( SUM=0; while read SIZE; do SUM=$(($SUM+$SIZE)); done; echo "$(($SUM/1024/1024/1024))GB" ) 

El punto es que hago una subcamada con () que contiene mi variable SUMA y el tiempo, pero canalizo en el todo () en lugar de en el propio tiempo, lo que evita el gotcha.