2

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.

Raphael
  • 2,055

2 Answers2

4

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
watael
  • 911
-1

Try if [ x${answer} = "xy" ];. test does need something before =

Anthon
  • 79,293