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?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityI 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.
Jun 22, 2018 at 3:47
<<<$(
is < <(
. Using here documents causes problems. E.g. they ignore NULL bytes, like when the command find … -print0
is used.
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.