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?
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?
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:
< <(find ...)
instead of like so <<<(find ...)
.... yours is the latter and that seems incorrect.
– Alexander Mills
Jun 22 '18 at 03:47
<<<$(
is < <(
. Using here documents causes problems. E.g. they ignore NULL bytes, like when the command find … -print0
is used.
–
Jun 13 '22 at 23:20
i
to survive past the end of the loop, but does not address the other issues still in the code. Also, note that if the user wants the last value found by find
, there are better ways to do this that would not break due to the presence of whitespaces in pathnames.
– Kusalananda
Mar 25 '23 at 14:58
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
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 '23 at 14:53