Почему мой счетчик Bash reset после цикла while
У меня есть Bash script, где я хочу подсчитать, сколько всего было сделано при переходе через файл. Счетчик, кажется, работает внутри цикла, но после него переменная кажется reset.
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
Вышеуказанный результат - это что-то одно: строки
Done entry 1
Done entry 2
Finished writing /blah, 0 keys
Выход, который я хочу:
Done entry 1
Done entry 2
Finished writing /blah, 2 keys
Я не совсем уверен, почему nKeys 0 после цикла:( Я предполагаю, что это что-то основное, но проклятое, если я могу это заметить, несмотря на просмотр http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html и другие ресурсы.
Пальцы скрестились, кто-то другой может посмотреть на него и пойти "ну, а ты..."
Ответы
Ответ 1
В только что выпущенном Bash 4.2 вы можете сделать это, чтобы предотвратить создание подоболочки:
shopt -s lastpipe
Кроме того, как вы, вероятно, увидите по предоставленной Игнасио ссылке, у вас есть Бесполезное использование cat
.
while read -r line
do
...
done < afile
Ответ 2
Как упоминалось в принятом ответе, это происходит потому, что в каналах появляются отдельные подпроцессы. Чтобы избежать этого, command grouping
был лучшим вариантом для меня. То есть, делая все после трубы в подоболочке.
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
}
Теперь он будет правильно сообщать значение $nKeys
"(то есть, что вы пожелаете).
Ответ 3
Я пришел к желаемому результату следующим образом, не используя трубы или здесь документы
#!/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