Question

(this is indirectly a part of a much larger homework assignment)

I have something like

    while read LINE
    do
        stuff-done-to-$LINE
        echo "Enter input:"
        read INPUT
        stuff-done-to-$INPUT
    done < infile

I can't find a successful way of using the console/default stdin for the second read, instead of the redirected stdin.

Needs to be pure bourne script.

Was it helpful?

Solution

I believe this is supported in the Bourne shell:

exec 3<doc.txt
while read LINE <&3
do
    stuff-done-to-$LINE
    # the next two lines could be replaced by: read -p "Enter input: " INPUT
    echo "Enter input:"
    read INPUT
    stuff-done-to-$INPUT
done < infile

Input is alternated between the file and the user. In fact, this would be a neat way to issue a series of prompts from a file.

This redirects the file "infile" to the file descriptor number 3 from which the first read gets its input. File descriptor 0 is stdin, 1 is stdout and 2 is stderr. You can use other FDs along with them.

I've tested this on Bash and Dash (on my system sh is symlinked to dash).

Of course it works. Here's some more fun:

exec 3<doc1.txt
exec 4<doc2.txt
while read line1 <&3 && read line2 <&4
do
    echo "ONE: $line1"
    echo "TWO: $line2"
    line1=($line1) # convert to an array
    line2=($line2)
    echo "Colors: ${line1[0]} and ${line2[0]}"
done

This alternates printing the contents of two files, discarding the extra lines of whichever file is longer.

ONE: Red first line of doc1
TWO: Blue first line of doc2
Colors: Red and Blue
ONE: Green second line of doc1
TWO: Yellow second line of doc2
Colors: Green and Yellow

Doc1 only has two lines. The third line and subsequent lines of doc2 are discarded.

OTHER TIPS

You can read/write the user's terminal through /dev/tty, this is independent of what shell you are using and whether stdin/stdout are redirected, so you just need:

echo "Enter input:" > /dev/tty
read INPUT < /dev/tty

This should to work:

for LINE in `cat infile`; do
   stuff-done-to-$LINE
   echo "Enter input:"
   read INPUT
   stuff-done-to-$INPUT
done

You can't. There's no default stdin and redirected stdin. There is stdin, and what it is connected to is either the console, or the file.

The only thing you can do is to do a while using a counter on the number of lines of your file. Then, extract each line using some smart use of sed or tail+head. You cannot use while read line because you would not have any way of differentiating the read from console and the read from the file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top