Statements: While

When you use while to process file data line by line, the use of a a pipe to feed the while loop is straightforward and conventional:

IFS=$'\n'
cat "${filename}" | while read -r line
do
   printf "%s\n" "${line}"
done

Note

What’s been written about resetting IFS in for loops is also true in while loops. The code is omitted for readability.

But is also comes with its drawbacks. Due to the pipe, the while loop is executing in a subshell, so all state changes in the while loop will be invisible to the executing script:

local error_found

IFS=$'\n'
cat "${filename}" | while read -r line
do
   case "${line}"
      *error*)
         error_found='YES'
         break
      ;;
   esac
done

# this will never be true
if [ "${error_found}" = 'YES' ]
then
   printf "There were errors\n" >&2
fi

Somewhat ungainly looking, but better in actual usage, is the nice bash feature <( :

while read -r line
do
   printf "%s\n" "${line}"
done < <( cat "${filename}" )

Or, if the input is text stored in a local variable:

IFS=$'\n'
while read -r line
do
   printf "%s\n" "${line}"
done <<< "${lines}"