In the following BASH script code:
while read -r line do if [some_condition]; then do_thing1 do_thing2 continue fi done < $SOME_VAR
What is the meaning of the last line? Specifically, what is being done with the value of $SOME_VAR?
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 community
< is the shell indirection operator. It takes the provided file, and uses it as standard input for the preceding command. That command would be roughly analagous to:
cat $SOME_VAR | while read -r line; do if stuff; then consequence else otherstuff fi done
SOME_VAR were not assigned to a file in the current working directory (or the full path to a file) the shell would throw a
No such file or directory error.
The other two answer's already covered most aspects of it. I would like to add that, to understand this syntax you should interpret the
while ... done as a single but complex statement, and
$SOME_VAR is fed to this statement as
stdin. It will be consumed whenever there is a need to read from
stdin. In this case the
read statement. There is actually no difference with the standard
cmd <in >out syntax.
In a very short terms,
< redirects file specified to the right of the
< symbol into
stdin stream of whatever command or group of commands you're executing.
while read -r line; do...done < input.txt is standard way to read a file line by line. While, of course,
$SOME_VAR doesn't have to be text file - can be named pipe among other things - this is the usual way and is used to avoid problems with word splitting in shell.
Often new to shell scripting think they can do something like
for line in $(cat file.txt) but if each line has multiple words on it separated by spaces, the for loop will be processing each word instead of each line. Something like this:
$ for i in $(cat input.txt); do echo "$i" ; done one two three four
That's not good. By contrast, while loop lets you process whole line without issues.
$ while read -r line; do echo "$line" ;done < input.txt one two three four
You might be wondering why not just use
cat | while read -r line..., but that's extra process and useless use of cat.
Redirection into stdin stream of a loop can be done with other things as well. If you are using
bash that supports
<<<, you could send a string literal of text to your while loop.
while read -r line;do # do something with line done <<< "Hello World"
A redundant example ? Yes, but proves the point that such syntax is more about redirecting input to while loop.