Perché il mio contatore Bash viene ripristinato dopo il ciclo while

Ho uno script Bash in cui voglio contare quante cose sono state fatte durante il looping di un file. Il conteggio sembra funzionare all’interno del ciclo ma dopo di esso la variabile sembra resettata.

nKeys=0 cat afile | while read -r line do #...do stuff let nKeys=nKeys+1 # this will print 1,2,..., etc as expected echo Done entry $nKeys done # PROBLEM: this always prints "... 0 keys" echo Finished writing $destFile, $nKeys keys 

L’output di cui sopra è qualcosa di solo le linee di:

 Fatto la voce 1
 Fine entrata 2
 Finito di scrivere / blah, 0 chiavi

L’output che voglio è:

 Fatto la voce 1
 Fine entrata 2
 Finito di scrivere / blah, 2 chiavi

Non sono del tutto sicuro del motivo per cui nKeys è 0 dopo il ciclo 🙁 Presumo che sia qualcosa di semplice ma dannato se riesco a individuarlo nonostante guardi http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html e altre risorse.

Incrociando le dita qualcun altro può guardarlo e andare “beh, bene! Devi …”!

Nel Bash 4.2 appena rilasciato, puoi fare ciò per evitare di creare una subshell:

 shopt -s lastpipe 

Inoltre, come probabilmente vedrai nel link che Ignacio ha fornito, hai un uso inutile di cat .

 while read -r line do ... done < afile 

Come accennato nella risposta accettata, ciò accade perché i tubi generano sottoprocessi separati. Per evitare ciò, il command grouping è stata l’opzione migliore per me. Cioè, facendo tutto dopo la pipe in una subshell.

 nKeys=0 cat afile | { while read -r line do #...do stuff let nKeys=nKeys+1 # this will print 1,2,..., etc as expected echo Done entry $nKeys done # PROBLEM: this always prints "... 0 keys" echo Finished writing $destFile, $nKeys keys } 

Ora riporterà il valore di $nKeys “correttamente” (cioè ciò che desideri).

Sono arrivato al risultato desiderato nel seguente modo senza usare pipe o qui documenti

 #!/bin/sh counter=0 string="apple orange mango egg indian" str_len=${#string} while [ $str_len -ne 0 ] do c=${string:0:1} if [[ "$c" = [aeiou] ]] then echo -n "vowel : " echo "- $c" counter=$(( $counter + 1 )) fi string=${string:1} str_len=${#string} done printf "The number of vowels in the given string are : %s "$counter echo