user3055756
user3055756

Reputation: 155

Reading from a file in bash without using the standard loop - non-typical use case

I am familiar with the following code to read every line of a file and perform some command.

while read -r line; do
  echo "$line"
done < filename

The above loop is driven by each line in the file with a block of operations performed in the loop.

I have a script with nested loops that spawn and control threads. I want to be able to pull a line at a time from the file by command in the loop instead of having the line frame the loop. For example, in other languages, there would be an fopen() then an fread() and an fclose() toward the end of the program to clean up. Is there an equivalent in bash?

I'm using Ubuntu 18.04 LTS and bash 4.4.20

Upvotes: 0

Views: 629

Answers (1)

dash-o
dash-o

Reputation: 14448

In bash, you can open a file using the 'exec' command. Assuming no other input files, you can redirect stdin. If stdin is used for something else, consider opening the file on a different file descriptor (3, 4, ...). You can not use 0, 1 and 2 and they are already associated with stdin/stdout/stderr.

Using stdin:

exec < filename

read ...
if [ ... ] ; then
    read ...
fi

# Close
exec <&-

Using a different file descriptor

exec 3<filename

read -u3 ...
if [ ... ] ; then
    read -u3 ...
fi
exec 3<&-

Note that unlike other environment, the code has to choose a distinct file descriptor to use, which can be tricky if there are many files to open at the same time. Better solution, based on @wjandrea comment

exec {myfile}<filename

read -u$myfile ...
if [ ... ] ; then
    read -u$myfile ...
fi
exec $myfile<&-

Upvotes: 1

Related Questions