I want to have a line break after prompt while using the cowsay function in the prompt :

read -p "$(cowsay "do you know this word?") \n" answer

there are multiple answers to this problem :



However the answers use the '' notation, which doesn't resolve the cowsay command

  • Something like this? cowsay "do you know this word?" ; read answer
    – ctx
    Nov 25, 2017 at 13:21

1 Answer 1


Why would you use the -p option for which you'd need the bash shell?

Just do:

cowsay "do you know this word?"
read answer

In bash, the -p option is only useful in conjunction with -e (another bash extension which makes bash's read behave like zsh's vared) where bash may need to redraw the prompt on some occasions (like upon Ctrl+L). But then, you would probably not need nor want it to redraw that prompt when it's several lines.

If you wanted to, you could always do:

read -ep "$(cowsay "do you know this word?")"$'\n' answer

(here using ksh93's $'...' form of quoting that understands C-like escape sequences)


read -ep "$(cowsay "do you know this word?")
" answer

More generally, the problem is that command substitution strips newline characters (not just one, all of them which could be considered a bug/misfeature¹) from the end of the command's output.

To work around that, the usual trick is to do:

output=$(cowsay "do you know this word?"; echo .)
read -p "$output" answer

That is, add .\n to the output. Command substitution strips the \n and we strip the . with ${output%.} leaving the whole command's output (provided it doesn't contain NUL characters in shells other than zsh, and that it's valid text in the current locale in yash).

For the record, in other Korn-like shells, the syntax for read to issue a prompt by itself is with:

read 'answer?prompt: '

The Korn shell would also redraw that prompt when reading from the terminal and an editor option has been enabled (like with set -o emacs or set -o vi). zsh also supports that syntax for compatibility, but the line editor is only used for vared, not for read there.

¹ for instance, it makes things like basename=$(basename -- "$file") wrong, as it could strip newline characters from the end of the file name, not just the one added by basename

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .