86
 read -p "Please Enter a Message:" message

How can I add a line break after Message:?

ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
Strawberry
  • 66,024
  • 56
  • 149
  • 197
  • 1
    You might consider updating the accepted answer to [this one](http://stackoverflow.com/a/15696250/1048539) as it's far less hacky (and less confusing to us future visitors...). – enderland Feb 12 '16 at 16:21
  • If you want to include shell variables in the prompt, then I think you’re going to need to use the, e.g., `read -p "$name, Please Enter a Message:"$'\n' message` form — described in the answer at https://stackoverflow.com/a/39581815/441757 — because you can’t use shell variables in the all-single-quoted `read -p $'Please Enter a Message:\n' message` form. – sideshowbarker Jun 10 '22 at 04:43

8 Answers8

102

Just looking for the exact same thing. You can use:

# -r and -e options are unrelated to the answer.
read -rep $'Please Enter a Message:\n' message

And it will work exactly as asked:

Please enter a Message:
_

Here is an extract from the bash manpage explaining it:

Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:

  • (...)
  • \n new line
  • (...)

The expanded result is single-quoted, as if the dollar sign had not been present.

Took me a while to find out.

Note that single quotes and double quotes behave differently in this regard:

A double-quoted string preceded by a dollar sign ($) will cause the string to be translated according to the current locale. If the cur- rent locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.

ferhtgoldaraz
  • 1,693
  • 3
  • 15
  • 20
  • @t-j-crowder This is a better way, the one [T.J. Crowder](http://stackoverflow.com/users/157247/t-j-crowder) was hinting to :) – dmitri Jul 18 '13 at 02:54
  • 1
    what does `-e` exactly do? it works with me without that `-e`, `-e` causes only for me that `-s` doesn't work any more. – Mohammed Noureldin Aug 16 '17 at 02:59
  • For those wondering, $'something' aka dollar-string seems to be POSIX-compliant (see https://mywiki.wooledge.org/Bashism for short-info, http://austingroupbugs.net/view.php?id=249 for more detail). – imme Oct 31 '18 at 10:45
50

I like Huang F. Lei's answer, but if you don't like the literal line break, this works:

read -p "Please Enter a Message: `echo $'\n> '`" message

Shows:

Please Enter a Message:
> _

...where _ is where the cursor ends up. Note that since trailing newlines are usually dropped during command substitution, I've included the > afterward. But actually, your original question doesn't seem to want that prompt bit, so:

# Get a carriage return into `cr` -- there *has* to be a better way to do this
cr=`echo $'\n.'`
cr=${cr%.}

# Use it
read -p "Please Enter a Message: $cr" message

Shows

Please Enter a Message:
_

There has to be a better way, though.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
46

Here's an improvement on the accepted answer that doesn't require spawning a subshell:

read -p "Please Enter a Message:"$'\n' message

From the GNU Bash reference manual:

Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.

augurar
  • 12,081
  • 6
  • 50
  • 65
18
$ read -p "Please Enter a Message:
> " message
Please Enter a Message:

Typing a "newline" between ':' and '"' directly.

Huang F. Lei
  • 1,835
  • 15
  • 23
  • 1
    neat solution, but might confuse someone reading the code later. – Alnitak Nov 28 '10 at 09:19
  • 1
    It's what works for me, because I also have a variable, and with the `read -p "$(echo -e 'Please Enter a Message: \n\b')" message` solution, it prints the variable name literally. This solution expands properly. – aliteralmind Jan 13 '15 at 03:46
12

Just to improve the answers of Huang F. Lei and of T.J. Crowder which I like (and added +1) .. You can use one of the following syntaxes too, which basically are the same, it depends on your taste (I prefer the first one):

read -p "$(echo -e 'Please Enter a Message: \n\b')" message
read -p "`echo -e 'Please Enter a Message: \n\b'`" message

which both will produce the following output:

Please Enter a Message: 
_

where _ is the cursor.
In case you need a newline in any part of the string but the end, you can use \n, for example

read -p "`echo -e '\nPlease Enter\na Message: '`" message

will produce

.
Please Enter
a Message: _

where . is a blank first new line and _ is the cursor.

Only to add a final trailing newline you have to use \n\b as in my first example

Community
  • 1
  • 1
Luca Borrione
  • 16,324
  • 8
  • 52
  • 66
4

From the bash manpage:

-p prompt
   Display prompt on standard error, without a trailing new-
   line, before attempting to read any input.  The prompt is
   displayed only if input is coming from a terminal.

So, not with read itself, and putting \n in the message string just echoes \n. The answer should be simple though - don't get read to display the prompt:

echo "Please Enter a Message:" 1>&2
read message
Alnitak
  • 334,560
  • 70
  • 407
  • 495
0
read -p "$(printf 'Please Enter a Message:\n')" message

With printfyou can use \n for line breaks.

TheAlphaGhost
  • 151
  • 10
-3

read -p "Please Enter a Message:Return" message

n.st
  • 946
  • 12
  • 27
Ruggero Turra
  • 16,929
  • 16
  • 85
  • 141