Pattern: Missing use of while read
loop
Issue: -
For loops by default (subject to $IFS
) read word by word. Additionally, glob expansion will occur.
Example of incorrect code:
for line in $(cat file | grep -v '^ *#')
do
echo "Line: $line"
done
Example of correct code:
grep -v '^ *#' < file | while IFS= read -r line
do
echo "Line: $line"
done
or without a subshell (bash, zsh, ksh):
while IFS= read -r line
do
echo "Line: $line"
done < <(grep -v '^ *#' < file)
or without a subshell, with a pipe (more portable, but write a file on the filesystem):
mkfifo somepipe
grep -v '^ *#' < file > somepipe &
while IFS= read -r line
do
echo "Line: $line"
done < somepipe
rm somepipe
If you want to read word by word, you should still use a while read loop (e.g. with read -a
to read words into an array).
Rare reasons for ignoring this message is if you don't care because your file only contains numbers and you're not interested in good practices, or if you've set $IFS
appropriately and also disabled globbing.