Nick Bull Nick Bull - 6 months ago 9
Bash Question

`read` output to variable does not echo to console window

I have this script:

function input_message {
echo -e "$1: "
while read -r response; do
case $response in
"")
return 1
;;
*)
echo $response
;;
esac
break
done
}


And I am trying to do the following in another script:

INPUTVAR="$(input_message 'Input a value')"


However, what happens on the console window when this is run is as follows:

nick@laptop:~$ INPUTVAR="$(input_message 'Input a value')"
This is my input
Input a value: This is my input


Of course, I'd expect the function to do this:

nick@laptop:~$ INPUTVAR="$(input_message 'Input a value')"
Input a value: This is my input
This is my input


What's the correct way to achieve this? I have tried various types of command expansion techniques and can't seem to get it right :(

Answer

There is a missing { in the function declaration.

The echo in the function does write reponse variable's value to standard output.

INPUTVAR=$(...) captures the standard output of the command executed in between (...) and assigned these outputs to INPUTVAR. That is why nothing is visible in the console.

When I test the function, I do not get the same result as you.

read has a -p option to display a prompt on standard error, which is going to be displayed in the console, when standard error is not redirected to something else.

Give a try to this, to both print to the console and assign a value to INPUTVAR:

$ cat fnlib.sh 

function input_message() {
    while read -r -p "${1}: " response; do
        case $response in
            "")
                return 1
                ;;
            *)
                printf "%s" "${response}"
                printf "%s\n" "${response}" >&2
                ;;
            esac
        break
    done
}

$ . fnlib.sh

$ INPUTVAR="$(input_message 'Input a value')"
Input a value: This is my input
This is my input

A second test with no value provided:

$ INPUTVAR="$(input_message 'Input a value')"
Input a value: 

If user enters nothing and press the [ENTER] key, the function prints nothing to standard input, so INPUTVAR variable is assigned the empty string.