60

I have a script that process a folder, and count the files in the mean time.

i=1
find tmp -type f | while read x
do 
   i=$(($i + 1))
   echo $i
done
echo $i

However, $i is always 1, how do I resolve this?

1

2 Answers 2

78

In your example the while-loop is executed in a subshell, so changes to the variable inside the while-loop won't affect the external variable. This is because you're using the loop with a pipe, which automatically causes it to run in a subshell.

Here is an alternative solution using a while loop:

i=1
while read x; do
   i=$(($i + 1))
   echo $i
done <<<$(find tmp -type f)
echo $i

And here is the same approach using a for-loop:

i=1
for x in $(find tmp -type f);
do 
   i=$(($i + 1))
   echo $i
done
echo $i

For more information see the following posts:

Also look at the following chapter from the Advanced Bash Scripting Guide:

6
  • 2
    regarding the first solution, isn't it process substitution like so < <(find ...) instead of like so <<<(find ...) .... yours is the latter and that seems incorrect. Jun 22, 2018 at 3:47
  • @AlexanderMills The <<< operator is called a here-string.
    – igal
    Feb 17, 2019 at 22:11
  • 1
    solution using for-loop doent work if the output contains spaces; but while-loops works Sep 23, 2019 at 10:54
  • The "for" loop is the answer I've been looking for! :)
    – fig
    Aug 31, 2021 at 10:38
  • 2
    A simpler version of <<<$( is < <(. Using here documents causes problems. E.g. they ignore NULL bytes, like when the command find … -print0 is used.
    – anon
    Jun 13, 2022 at 23:20
9
i=1
while read x
do
   i=$(($i + 1))
   echo $i
done < <(find tmp -type f)
echo $i

https://stackoverflow.com/questions/7390497/bash-propagate-value-of-variable-to-outside-of-the-loop

1
  • This would solve the immediate issue of allowing the variable i to survive past the end of the loop, but the answer does not explain why this works. Also, correcting the many other issues still present in the code would be trivial.
    – Kusalananda
    Mar 25 at 14:53

Not the answer you're looking for? Browse other questions tagged .