Veuillez m'expliquer pourquoi la toute dernière déclaration echo
est vide? Je suppose que XCODE
est incrémenté dans la boucle while à la valeur 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 du ++XCODE
méthode
XCODE=`expr $XCODE + 1`
et il 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 le montre pas.
Parce que vous dirigez la boucle while, un sous-shell est créé pour exécuter la boucle while.
Maintenant, ce processus enfant a sa propre copie de l'environnement et ne peut transmettre aucune variable à son parent (comme dans tout processus unix).
Par conséquent, vous devrez vous restructurer pour ne pas vous perdre dans la boucle. Vous pouvez également exécuter une fonction, par exemple, et echo
la valeur à renvoyer par le sous-processus.
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 le 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")
Cela devrait également fonctionner (car echo et while sont dans le même sous-shell):
#!/bin/bash
cat /tmp/randomFile | (while read line
do
LINE="$LINE $line"
done && echo $LINE )
Une autre option:
#!/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
EDIT: Ici, xsel est une nécessité (installez-le). Vous pouvez aussi utiliser xclip: xclip -i -selection clipboard
au lieu 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
voir si ces changements aident
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)
J'ai contourné ça quand je fabriquais mon propre petit duo:
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" )
Le fait est que je crée un sous-shell avec () contenant ma variable SOMME et le moment, mais que je me faufile dans la totalité () au lieu de dans la durée elle-même, ce qui évite le gotcha.