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