J'ai un problème dans l'un de mes scripts shell. A demandé à quelques collègues, mais ils secouent tous la tête (après quelques égratignures), alors je suis venu ici pour une réponse.
Selon ma compréhension, le script suivant devrait afficher "Le nombre est 5" à la dernière ligne. Sauf que ce n'est pas le cas. Il imprime "Le compte est 0". Si le "while read" est remplacé par un autre type de boucle, cela fonctionne très bien. Voici le script:
echo "1"> input.data echo "2" >> input.data echo "3" >> input.data echo "4" >> input.data echo "5" >> input.data CNT = 0 cat input.data | en lisant; faire laissez CNT ++; echo "Compter jusqu'à $ CNT" terminé echo "Count is $ CNT"
Pourquoi cela se produit-il et comment puis-je l'éviter? J'ai déjà essayé cela dans Lenny et Squeeze de Debian, le même résultat (c'est-à-dire bash 3.2.39 et bash 4.1.5. J'admets pleinement que je ne suis pas un assistant de script shell, alors tout pointeur serait apprécié.
C'est une sorte d'erreur "commune". Les pipes créent des SubShells, ainsi, il
while read
s’exécute sur un shell différent de celui de votre script, ce qui fait que votreCNT
variable ne change jamais (seulement celle qui se trouve dans le sous-shell du pipe).Regroupez le dernier
echo
avec le sous-shellwhile
pour le réparer (il existe de nombreuses autres façons de le réparer, en voici un. Les réponses d'Iain et d'Ignacio en ont d'autres.)Longue explication:
CNT
sur votre script la valeur 0;|
àwhile read
;$CNT
variable est exportée vers le SubShell avec la valeur 0;CNT
valeur à 5;echo
votreCNT
valeur initiale de 0.la source
Cela marche
la source
let CNT++
qui devrait plutôt êtreCNT="$((CNT+1))"
de faire appel à un développement arithmétique conforme à POSIX . Le reste est déjà portable.Essayez plutôt de transmettre les données dans un sous-shell, comme s'il s'agissait d'un fichier avant la boucle while. Ceci est similaire à la solution de lain, mais suppose que vous ne voulez pas de fichier intermittent:
la source