reading stdin multiple times in bash

2019-02-22 10:24发布

问题:

I'm trying to read from stdin multiple times in a shell script, with no luck. The intention is to read a list of files first (which are read from the stdin pipe), and then read twice more to get two strings interactively. (What I'm trying to do is read a list of files to attach in an email, then the subject and finally the email body).

So far I have this:

photos=($(< /dev/stdin))

echo "Enter message subject"
subject=$(< /dev/stdin)

echo "Enter message body"
body=$(< /dev/stdin)

(plus error checking code that I omit for succintness)

However, this gets an empty subject and body presumably because the second and third redirections get EOF.

I've been trying to close and reopen stdin with <&- and stuff but it doesn't seem to work that way.

I even tried using a separator for the list of files, using a "while; read line" loop and break out of the loop when the separator was detected. But that didn't work either (??).

Any ideas how to build something like this?

回答1:

So what I ended up doing is based on ezpz's answer and this doc: http://www.faqs.org/docs/abs/HTML/io-redirection.html Basically I prompt for the fields first from /dev/tty, and then read stdin, using the dup-and-close trick:

# close stdin after dup'ing it to FD 6
exec 6<&0

# open /dev/tty as stdin
exec 0</dev/tty

# now read the fields
echo "Enter message subject"
read subject
echo "Enter message body"
read body

# done reading interactively; now read from the pipe
exec 0<&6 6<&-
fotos=($(< /dev/stdin))

Thanks!



回答2:

You should be able to use read to prompt for the subject and body:

photos=($(< /dev/stdin))

read -rp "Enter message subject" subject

read -rp "Enter message body" body


回答3:

Since it is possible that you have a varying number of photos, why not just prompt for the known fields first and then read 'everything else'. It is much easier than trying to get the last two fields of an unknown length in an interactive manner.



标签: bash stdin