0

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?

4

The < is the input redirection operator, $SOME_VAR probably contains the name of a file. Together, they'd cause the loop to read lines from the file.

| improve this answer | |
2

< 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

If 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.

| improve this answer | |
  • 1
    The difference comes when the file in SOME_VAR can't be opened for reading. With cat "$SOME_VAR" (note quoting BTW), cat will complain. With done <"$SOME_VAR", the shell will complain. – Kusalananda Jan 30 '18 at 17:47
1

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.

| improve this answer | |
1

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.

The 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.

See also:

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.