Use rlwrap, a readline wrapper.
From man rlwrap
rlwrap runs the specified command, intercepting user input in order to provide readline's line editing, persistent history and completion.
and from the Debian rlwrap
package description:
This package provides a small utility that uses the GNU readline library to allow the editing of keyboard input for any other command. Input history is remembered across invocations, separately for each command; history completion and search work as in bash and completion word lists can be specified on the command line.
A very simple example script:
#! /bin/bash
ynm=(Yes No Maybe)
reply=$(rlwrap -S 'Do you want to continue? ' -H ~/.jakob.history
-e '' -i -f <(echo "${ynm[@]}") -o cat)
echo "reply='$reply'"
This uses rlwrap
's one-shot mode to run cat
(to get stdin) but accept only one line of input. -o cat
is rlwrap
's recommended substitute for read
.
Command-line history is stored in ~/.jakob.history
, and the completion items are in the bash array $ynm
.
rlwrap
expects a file as the argument to the -f
option. Fortunately, we can use process subsitution <(echo "${ynm[@]}")
to supply an array rather than a file.
-i
enables case-insensitivity for completions.
The -e ''
stops rlwrap
from appending a space after a successful completion (so that $reply
ends up containing, e.g., 'Maybe'
rather than 'Maybe '
with a trailing space)
If you want a default already pre-typed on the input line, you could use the -P
or --pre-given
option - e.g. add -P Yes
to the rlwrap
command in the example script above. The user would only have to hit Enter to accept or backspaces or Ctrl-U to erase the default (as is normal for readline
in emacs mode).
see man rlwrap
for details and more options. e.g. you can enable filename completion with -c
or --complete-filenames
.
Check if rlwrap
is packaged for your distro (it is for Debian and probably Ubuntu/Mint/etc, at least) before downloading and compiling the source.
read
prompt. Similar, quite possibly, but definitely different.