Getting user input after stdin has been redirected, in a bourne script

孤人 提交于 2020-01-22 15:33:09

问题


(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 &lt 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.


回答1:


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.




回答2:


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



回答3:


This should to work:

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



回答4:


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.



来源:https://stackoverflow.com/questions/1385380/getting-user-input-after-stdin-has-been-redirected-in-a-bourne-script

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!