Bash: Reading input from the console while looping over output of command

If you are using the direct output of a command to feed a while loop in BASH, you may still want to take user input inside that loop.  For example, if you need the user to confirm each line by pressing <ENTER>.

Take a simple example like this:

grep one test.txt | while read -r line; do
  echo "Processing $line"
  read
done

You may (wrongly!) expect this to loop over each matched line, and allow the user to press <ENTER> on each match.  It will NOT provide the user a chance to respond because the input of read will come from the output of the initial command.  So you need to explicitly specify where you want the input to come from.

The simplest way is to explicitly specify input as coming from the user console like:

read < /dev/tty

If you want to loop over that file line-by-line allowing the user to press <ENTER> for each find:

grep one test.txt | while read -r line; do
  echo "Processing $line"
  read < /dev/tty
done

There are of course multiple ways to express this in Bash.  This is equivalent, but with a different syntax.

while read -r line ; do
  echo "Processing $line"
  read < /dev/tty
done < <(grep one test.txt)

 

REFERENCES

https://stackoverflow.com/questions/6883363/read-input-in-bash-inside-a-while-loop (specify input from /dev/tty)

https://stackoverflow.com/questions/16317961/how-to-process-each-line-received-as-a-result-of-grep-command/16318041#16318041 (use of IFS , read -r does not trim leading/trailing spaces)

http://tldp.org/LDP/abs/html/loopcontrol.html (bash looping control)

https://devhints.io/bash

https://stackoverflow.com/questions/12916352/shell-script-read-missing-last-line (use || [ -n “$line”] to get last line using while)

NOTES

Example of parsing words from single line

#!/bin/bash

echo ==test1====================
# there is a space after quote, IFS looking for space or newline
IFS=$" 
"
for word in $(cat test.txt) 
do
  echo "test1 $word"
  read < /dev/tty
done

echo ==test2====================
# last line would not go through loop unless we have OR
cat test.txt | while read -d ' ' word || [ -n "$word" ]; do
  echo "test2 $word"
  read < /dev/tty 
done