The implicit subshell in a pipe to while can make it difficult to track down bugs.
last_line='NULL'
your_command | while read line; do
last_line="${line}"
done
# This will output 'NULL'
echo "${last_line}"
Use a for loop if you are confident that the input will not contain spaces or special characters (usually, this means not user input).
total=0
# Only do this if there are no spaces in return values.
for value in $(command); do
total+="${value}"
done
Using process substitution allows redirecting output but puts the commands in an explicit subshell rather than the implicit subshell that bash creates for the while loop.
total=0
last_file=
while read count filename; do
total+="${count}"
last_file="${filename}"
done < <(your_command | uniq -c)
# This will output the second field of the last line of output from
# the command.
echo "Total = ${total}"
echo "Last one = ${last_file}"
Use while loops where it is not necessary to pass complex results to the parent shell - this is typically where some more complex "parsing" is required. Beware that simple examples are probably more easily done with a tool such as awk. This may also be useful where you specifically don't want to change the parent scope variables.
# Trivial implementation of awk expression:
# awk '$3 == "nfs" { print $2 " maps to " $1 }' /proc/mounts
cat /proc/mounts | while read src dest type opts rest; do
if [[ ${type} == "nfs" ]]; then
echo "NFS ${dest} maps to ${src}"
fi
done