110 votes

Missing title

S'il vous plaît, expliquez-moi pourquoi la toute dernière déclaration "echo" est vide. Je m'attends à ce qu'il soit incrémenté dans la boucle while à une valeur 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
 

J'ai essayé d'utiliser l'instruction suivante à la place de la méthode ++ XCODE

 XCODE=`expr $XCODE + 1`
 

et cela n'imprimera pas non plus en dehors de la déclaration while. Je pense que je manque quelque chose à propos de la portée variable ici mais la vieille page de manuel ne me la montre pas.

128voto

pixelbeat Points 12073

Parce que vous êtes à la tuyauterie dans la boucle while, un sous-shell est créé pour exécuter la boucle while. Maintenant, ce processus enfant a son propre exemplaire de l'environnement et on ne peut pas passer toute les variables de retour à son parent (comme dans tout processus unix).

Par conséquent, vous aurez besoin de restructurer, de sorte que vous n'êtes pas tuyauterie dans la boucle. Vous pouvez également exécuter dans une fonction, par exemple, et l'écho de la valeur que vous être renvoyée dans les sous-processus.

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

118voto

mweerden Points 4291

Le problème est que les processus assemblés avec un canal sont exécutés dans des sous-shell (et ont donc leur propre environnement). Tout ce qui se passe dans les while n'affecte rien en dehors du tuyau.

Votre exemple spécifique peut être résolu en réécrivant le tuyau en

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

ou peut-être

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

2voto

Kent Fredric Points 35592
  #!/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
 

voir si ces changements aident

2voto

freethinker Points 656

Une autre option consiste à exporter les résultats dans un fichier du sous-shell, puis à les lire dans le shell parent. quelque chose comme

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X