I've been googling this question to no avail. I'm automating a build process here at work, and all I'm trying to do is get version numbers and a tiny description of the build which may be multi-line. The system this runs on is OSX 10.6.8.

I've seen everything from using CAT to processing each line as necessary. I can't figure out what I should use and why.


read -d '' versionNotes

Results in garbled input if the user has to use the backspace key. Also there's no good way to terminate the input as ^D doesn't terminate and ^C just exits the process.

read -d 'END' versionNotes

Works... but still garbles the input if the backspace key is needed.

while read versionNotes
  echo "  $versionNotes" >> "source/application.yml"

Doesn't properly end the input (because I'm too late to look up matching against an empty string).

  • You're getting this information from the user, correct? – glenn jackman Apr 9 '12 at 23:14
  • Correct; I want the user to enter this information in the terminal when executing the script. – Robert K Apr 10 '12 at 11:22
  • 1
    You haven't made yourself clear, I'd rather say. – poige Jun 11 '12 at 10:33

man bash mentions «…

The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).


$ myVar=$(</dev/stdin)
this is test
$ echo $myVar
hello this is test
$ echo "$myVar"
this is test

and I agree this is worth mentioning — echo "$myVar" would have displayed the input as it was given.

| improve this answer | |
  • 1
    How to stop after multiline input? If I press Ctrl C it stops but the variable is not saved! – Porcupine Aug 13 '18 at 9:46
  • 2
    UNIX® terminals do have "discipline": en.wikipedia.org/wiki/Line_discipline • Check it out what does "eof" mean • Do read man stty, find out how to get current settings – poige Aug 13 '18 at 15:43
  • 2
    ctrl-d to stop. – freb Oct 23 '18 at 2:52

Try this:

user@host:~$ read -d '' x <<EOF
> mic
> check
> one
> two

Without line breaks:

user@host:~$ echo $x
mic check one two

With line breaks:

user@host:~$ echo "$x"
| improve this answer | |
  • 2
    -d '' is exactly what I needed. Thanks – Bruno Bronosky Mar 9 '17 at 22:53
  • @Bruno My pleasure; it's a tricky one. Especially at first glance, it looks fairly standard. Can be quite useful though, once you get the hang of the various idiosyncrasies. – voices Mar 11 '17 at 8:57

Refer to the excellent Bash Guide for all your bash scripting needs.

In particular the Bash FAQ contains this at number #1:

How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?

| improve this answer | |
  • You say to use read -r, but how do I get it to do so from STDIN? I did attempt to use read -r early on. – Robert K Apr 25 '12 at 17:17
  • It reads from stdin by default. – adaptr Apr 26 '12 at 7:17

I've solved this issue by dealing with each line until I came up with a blank line. It works well enough for my situation. But if someone wants to add a better solution, feel free to do so.

echo "---
notes: |" > 'version.yml'

while read line
  # break if the line is empty
  [ -z "$line" ] && break
  echo "  $line" >> "source/application.yml"
| improve this answer | |
  • 1
    Use read -r instead. – adaptr Apr 25 '12 at 13:26

You can start an editor like vim, pico...

${VISUAL:-${EDITOR:-vi}} source/application.yml
| improve this answer | |
  • Um... how does that answer the OP's question in any way ? – adaptr Apr 25 '12 at 13:27
  • He can start the editor from the script. – Mircea Vutcovici Apr 25 '12 at 14:46
  • And that accomplishes what, exactly ? He wants to use text from a file in the script, not write information to a file. – adaptr Apr 25 '12 at 15:05
  • He wasnts to read text from the user and write it to a file. Please read the comments added to the question. – Mircea Vutcovici Apr 25 '12 at 16:03

First a few corrections:

  1. To allow "edition" on the line use -e which uses readline (so you have the bash history and all editing features)
  2. -d only takes one character. E.g. from 'END' takes 'E' and whenever the user writes an 'E' the reading stops (I guess that's not what you want...)

There are a few possibilities to do this. I'd go for read line by line and stop when an empty line is found (though you could set any stop word):

unset tmp
while :
 read line
 [[ $line == "" ]] && tmp="${tmp:0:$((${#tmp}-1))}" && break
| improve this answer | |

You have several methods.

One of the simplest methods is:

echo $"MYVAR"

For example:

MYVAR=$(ls /)
echo $"MYVAR"
| improve this answer | |
  • Except I'm not executing a shell command like LS. I'm requesting multi-line input from the user. – Robert K Apr 10 '12 at 11:23
  • This is very bad practice; do not process the output of ls! – adaptr Apr 25 '12 at 13:14
  • @adaptr We've heard it all before, would you mind suggesting a good alternative, please? – voices Mar 11 '17 at 8:50

We are using a construct using xargs and ctrl-d for breaking. I'm not perfectly satisfied with it, but it certainly does the job of taking multi-line user input and stuffing that into a variable (formatting intact). (The first and third assignments add quotes around the contents of the xargs input.)

    printf '%s\n' "When finished hit ctrl-d on a new line to proceed.  " "" "" 
    # this will load the user's input into a variable instead of a file 
    reminderBody+=$( xargs -0 ) 

We use reminderBody as the body of an e-mail being sent by mail (via bash).

| improve this answer | |

See: http://tldp.org/LDP/abs/html/internal.html#READR

Use read and note that if you end a line with \ the newline is ignored. So you could do:


read -p "version: " version
echo $version

# enter some input and end long lines with "\", then plain enter at the end
read -p "description: " description
echo -e "$version\n$description >> yourfile.txt
| improve this answer | |
  • If I just wanted a paragraph with line breaks ignored, yes. But as this is a generated list of release notes for a build script, I need to be able to preserve those line breaks; I might try to enter a bulleted list, for example. – Robert K Apr 25 '12 at 13:09
  • The ABS is a monstrosity of horrific proportions. 90% of it is plain wrong. – adaptr Apr 25 '12 at 13:26
  • It's not that bad. – voices Mar 11 '17 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.