Unix & Linux
bash shell io-redirection test read
Updated Sat, 13 Aug 2022 02:20:55 GMT

Nested read fails


I have a list of filenames in a file and want to do let the user decide what to do with each. In bash, iterating over filenames is not trivial in itself, so I followed this answer:

#!/bin/bash
while IFS= read -r THELINE; 
do
  read -n 1 -p "Print line? [y/n] " answer;
  if [ ${answer} = "y" ];
  then
    echo "${THELINE}";
  fi;
done < tester;

When I try to execute this (on a non-empty file), I get an error at the if:

line 5: [: =: unary operator expected

My best guess is that answer is not set properly, which would be caused by using two calls of read in a "nested" fashion since the following works as expected:

#!/bin/bash
for THELINE in $(cat "tester");
do
  read -n 1 -p "Print line? [y/n] " answer;
  if [ ${answer} = "y" ];
  then
    echo "${THELINE}";
  fi;
done;

What is going on here?

I run bash 4.2.24(1)-release (x86_64-pc-linux-gnu) on 3.2.0-37-generic #58-Ubuntu x86_64 GNU/Linux.




Solution

First, the error from [ is because answer is empty, so [ sees three arguments: =, y and ]. Always put double quotes around variable substitutions: if [ "$answer" = "y" ].

The reason $answer is empty fd 0 is busy with the file input due to the redirection <tester over the while loop.

while IFS= read -r line <&3
do
    read -n 1 -p "Print line? [y/n] " answer
    if test "$answer" = "y"
    then
        echo "$line"
    fi
done 3< tester






External Links

External links referenced by this document: