Weblog entry #7 for drgraefy

bash read/readline prepopulation questions
Posted by drgraefy on Tue 4 Mar 2008 at 04:53
Tags: ,

So I'm trying to figure out how to prepopulate the prompt for the bash read function with text that could be edited and then passed to the readline output. For some reason I'm having an exceptionally hard time figuring out how to do this. It's either not possible, or I'm just having no luck. For example

The read help says that "One line is read from the standard input", but that doesn't actually seem to be the case:

servo:/tmp/cdtemp.VI3235 0$ foo=
servo:/tmp/cdtemp.VI3235 0$ read -e -p : foo
:asdf
servo:/tmp/cdtemp.VI3235 0$ echo $foo
asdf
servo:/tmp/cdtemp.VI3235 0$ foo=
servo:/tmp/cdtemp.VI3235 0$ echo -n asdf | read -e -p : foo
servo:/tmp/cdtemp.VI3235 1$ echo $foo

servo:/tmp/cdtemp.VI3235 0$ echo asdf >bar
servo:/tmp/cdtemp.VI3235 0$ read -e -p : foo < bar
servo:/tmp/cdtemp.VI3235 0$ echo $foo
asdf
servo:/tmp/cdtemp.VI3235 0$

This appears to indicate that read can accept input from a file, but not from a pipe. Why would that be?

Does anyone know how to prepopulate a read or readline prompt? Maybe it's not possible with read, but with some other function? It must be possible if I were to code it in C or something, cause plenty programs that do stuff like this (take the emacs mini-buffer, for instance).

 

Comments on this Entry

Posted by drgraefy (216.254.xx.xx) on Tue 4 Mar 2008 at 18:55
[ Send Message | View Weblogs ]

so I notice that the "echo -n foo | read.." line produces an error, and the redirect from file does not. read is probably complaining about the lack of newline in the echo bit, which is presumably why it's not returning the stdin into the output variable.

anyway, it's still a real shame as far as I'm concerned, since it means that the bash read is probably not able to do what I want: prepopulate a read input field with data. still looking for other ideas, if they're out there.

[ Parent | Reply to this comment ]

Posted by mcortese (213.70.xx.xx) on Fri 7 Mar 2008 at 11:53
[ Send Message | View Weblogs ]

Yes, read cannot do what you need. I suggest you simulate the pre-seeding with the ${x:-y} syntax.

myownread() {
	local x
	echo >&0 -e "$1$2\e[A"
	read >&0 -p "$1" x
	eval "$3='${x:-$2}'"
}

Then use it like this:

# Use:
# myownread PROMPT PRESEED VAR
myownread "Question? " "yes" aaa
echo $aaa

The above function works with bash and sh.

The only problem is that the \e[A sequence that forces the cursor up one line is terminal-specific (you can find the sequence that fits your term by pressing Control-V then the Up key).

[ Parent | Reply to this comment ]

Posted by drgraefy (74.66.xx.xx) on Fri 7 Mar 2008 at 13:50
[ Send Message | View Weblogs ]

That is really interesting, mcortese, and very clever. Thanks very much for the tip. It doesn't do exactly what I want, but it is a very interesting "simulation", as you say.

I thought about the problem more (with dkg), and realized that it's not an easy problem. the readline function has a fairly obtuse way to preseed the command line. it can't really be preseeded from stdin because it's trying to read the user input from stdin as well.

[ Parent | Reply to this comment ]

Posted by endecotp (86.6.xx.xx) on Sat 8 Mar 2008 at 23:39
[ Send Message | View Weblogs ]
I recall much frustration trying to understand why something|read didn't work, and what to use instead. I have two alternatives:

something > /tmp/foo
read < /tmp/foo

or

read <<EOF
`something`
EOF

[ Parent | Reply to this comment ]

User Login

Username:

Password:

[ Advanced Login ]

Register Account

Quick Site Search