开发者

reading multiple items semi-interactively from the user in bash

开发者 https://www.devze.com 2022-12-15 02:30 出处:网络
I\'m trying to read multiple items from the user 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 tw

I'm trying to read multiple items from the user 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?


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<&-
photos=($(< /dev/stdin))

Thanks!


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


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.


# Prompt and read two things from the terminal (not from stdin), then read stdin.
# The last line uses arrays, so is BASH-specific.  The read lines are portable.
# - Ian! D. Allen - idallen@idallen.ca - www.idallen.com
read -p "Enter message subject: " subject </dev/tty
read -p  "Enter message body: " body </dev/tty
photos=($(</dev/stdin))
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号