tags:

views:

726

answers:

3

Hi,

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?

+2  A: 

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.

ezpz
The reason that doesn't work for me is that I am trying to use a pipe to pass the list of photos. If I simply read the those fields before the list, the two first photos in the list end up being subject and email body, which is not what I want. (Of course, I could dictate that the subject and body must be passed in the first two lines of the input pipe, but that's much too ugly for me.)
alvherre
+2  A: 

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
Dennis Williamson
Thanks. That works if I am entering the data interactively. However, if I use a pipe (which is what I'm actually interested in), it doesn't. For example, I'm trying to do this: cat /tmp/somephotoids | sed -e 's/\(.*\)/DSC_\1.jpg/' | sendpics.shWhile I could workaround the issue by cut'n'pasting, I have spent enough time on doing it this way that I now consider it some sort of challenge.
alvherre
+2  A: 

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!

alvherre