Bash – How to output a suggestion for a user to accept and use as input

bashpromptvariable

What can I do to leave the cursor on the same line of the suggestion in a Bash script?

Bash version = 3.2.51

It's purpose is to suggest a string so that the user should only press Enter.

#!/bin/sh
echo "@@@@@@@@@@
@ Enter the new plarform name [for example: our-platform-7.26-2.17-res4]:
@@@@@@@@@@"
echo "our-platform-7.26-2.17-res4"
read SuggestDefaultPlatform

echo "Stored name: " ${SuggestDefaultPlatform}

which prompts:

@@@@@@@@@@
@ Enter the new plarform name [for example: our-platform-7.26-2.17-res4]:
@@@@@@@@@@ 
our-platform-7.26-2.17-res4
_

where the underscore "_" stands for the cursor.

I don't want to use a "Y/n" logic workaround, assigning a default value to the "SuggestDefaultPlatform" variable

SuggestDefaultPlatform='our-platform-7.26-2.17-res4';

and then prompt a question like:

Are you okay with `'our-platform-7.26-2.17-res4'` as your platform name? [Y/n]...

Instead the user might want to change just a few digits of a prompted suggestion and press Enter. See below the cursor "_" at the end of the "SuggestDefaultPlatform" variable:

@@@@@@@@@@
@ Enter the new plarform name [for example: our-platform-7.26-2.17-res4]:
@@@@@@@@@@ 
our-platform-7.26-2.17-res4_

so that the user can move the cursor, modify the suggestion and/or press Enter.

our-platform-7.26-2.17-res_
our-platform-7.26-2.17-re_
our-platform-7.26-2.17-r_
our-platform-7.26-2.17-_
our-platform-7.26-2.17_
our-platform-7.26-2.1_
our-platform-7.26-2.18-alpha1_

Press Enter.

which prompts:

Stored name: our-platform-7.26-2.18-alpha1

Best Answer

sh (as in the sh language specification) doesn't come with a line editor. Terminal drivers have a rudimentary line editor that allow for backspace and a few other keys to edit the entered line, but generally not arrow keys.

You can insert a default value into the terminal driver input buffer using the TIOCSTI ioctl like:

printf 'Please enter the value: '
value=the-default
perl -MPOSIX -e 'require "sys/ioctl.ph"; tcflush 0,2;
  ioctl(STDIN, &TIOCSTI, $_) or die "$!\n"
    for split "", join " ", @ARGV' "$value"
IFS= read -r value

Upon the read, the content of $value (the-default) will have been inserted as if typed.

Now, if you want a more advanced line editor like provided by libreadline where you can use arrow keys, you can use things like rlwrap (not a standard command though):

value=the-default
value=$(rlwrap -S 'Please enter the value: ' -P "$value" -o cat)

rlwrap is typically used to add a readline-like line editors to applications that don't have one. Above we're adding a line editor to cat, and using it in one-shot mode (-o), so that cat returns after one line is entered (though you can still enter more than one line with Ctrl+V, Ctrl-J like in bash.

If you're ready to use non-standard shells, zsh or bash have builtins for that using their own line editor.

In zsh:

value=the-default
vared -p 'Please enter the value: ' value

In bash:

value=the-default
IFS= read -re -i "$value" -p 'Please enter the value: ' value
Related Question