Problem with while loop reading every line of a text file

Hello,

I'm using RHEL 5.1 with bash. How to handle "read" inside while loop reading every line? Please see below:

#  cat /tmp/passwd_sample
CARRJ12:qVSn4ja4mFA72,..:20021:125:JULIAN CARR:/home/everyone:/bin/bash
HERCOT01:NK/3j2ZB4ZC7Q:20022:125:TOM HERCOCK:/home/everyone:/bin/bash
NIRMALA1:35ltVGpjHq.aM:20025:125:NIRMALA KESAVAN:/home/everyone:/bin/bash
KENNEC07:GR1AlScQIfLeI:20023:125:CARL KENNEALLY:/home/everyone:/bin/bash
STANH001:VTPzaDxM1f3ps:20024:125:OWEN STANHOPE:/home/everyone:/bin/bash
#

The below works as expected:

# cat /tmp/passwd_sample |while read line
> do
> echo "${line}"
> done
CARRJ12:qVSn4ja4mFA72,..:20021:125:JULIAN CARR:/home/everyone:/bin/bash
HERCOT01:NK/3j2ZB4ZC7Q:20022:125:TOM HERCOCK:/home/everyone:/bin/bash
NIRMALA1:35ltVGpjHq.aM:20025:125:NIRMALA KESAVAN:/home/everyone:/bin/bash
KENNEC07:GR1AlScQIfLeI:20023:125:CARL KENNEALLY:/home/everyone:/bin/bash
STANH001:VTPzaDxM1f3ps:20024:125:OWEN STANHOPE:/home/everyone:/bin/bash
#

But when I use "read" it outputs without any interaction (as read is supposed to wait for our input keys) and skips few lines as shown below:

# cat /tmp/passwd_sample |while read line
> do
> echo "${line}"
> echo "Press any key to continue ...."
> read any_key
> done
CARRJ12:qVSn4ja4mFA72,..:20021:125:JULIAN CARR:/home/everyone:/bin/bash
Press any key to continue ....
NIRMALA1:35ltVGpjHq.aM:20025:125:NIRMALA KESAVAN:/home/everyone:/bin/bash
Press any key to continue ....
STANH001:VTPzaDxM1f3ps:20024:125:OWEN STANHOPE:/home/everyone:/bin/bash
Press any key to continue ....
#

Please advise on what I'm doing wrong and how to fix it, thanks!!

both of these read operations work on the same stdin. you need to assign to a different fd and use that for one of them. the easiest way to do this is to ditch the useless use of cat (uuoc award).

while read line <&9; do
  echo "$line"
  echo "press enter key"
  read
done 9<passwd_sample

Now we redirect passwd_sample into fd 9 for the entire while block, yet only the first read operation operates on fd 9. in this way, we'll keep our position in the file with each iteration and read line-by-line but not interfere with the read that wants input from the terminal.

if you're using bash, you can use read -s -N 1 for grabbing a single key. otherwise you'll need to press enter rather than "any" key.

3 Likes

Thanks neutronscott for the solution & explanation :b: It worked.

As read exists 2 times it displays alternate lines & remaining lines were inputted as "press any keys". It's clear now :slight_smile:

On a different note, read -s -N 1 is NOT working on bash 3.2 (comes with RHEL 5) but it's working fine on bash 4.2 (RHEL 6).

Thanks again!!

Yeah, bash 3.2 didn't have -N only -n. It's almost the same. Try it and see if it has the correct effect.

Yep, I tried -n after posting here and it worked.

Thanks again for all the help & guidance!