Barton Chittenden
Barton Chittenden

Reputation: 4416

Line feed is being removed from echo when called in double-quotes

I'm trying to populate a shell variable called $recipient which should contain a value followed by a new-line.

$ set -x # force bash to show commands as it executes them

I start by populating $user, which is the value that I want to be followed by the newline.

$ [email protected]
+ [email protected]

I then call echo $user inside a double-quoted command substitution. The echo statement should create a newline after $user, and the double-quotes should preserve the newline.

$ recipient="$(echo $user)"
++ echo [email protected]
+ [email protected]

However when I print $recipient, I can see that the newline has been discarded.

$ echo "'recipient'"
+ echo ''\''recipient'\'''
'recipient'

I've found the same behaviour under bash versions 4.1.5 and 3.1.17, and also replicated the issue under dash.

I tried using "printf" rather than echo; this didn't change anything.

Is this expected behaviour?

Upvotes: 0

Views: 162

Answers (2)

shellter
shellter

Reputation: 37268

All shell versions will react the same way, this is nothing new in scripting.

The new-line at the end of your original assignment is not included in the variable's value. It only "terminates" the current cmd and signals the shell to process.

Maybe user="[email protected]\n" will work, but without context about why you want this, just know that people usually keep variables values separate from the formatting "tools" like the newline.

IHTH.

Upvotes: 1

William Pursell
William Pursell

Reputation: 212248

Command substitution removes trailing newlines. From the standard:

The shell shall expand the command substitution by executing command in a subshell environment (see Shell Execution Environment ) and replacing the command substitution (the text of command plus the enclosing "$()" or backquotes) with the standard output of the command, removing sequences of one or more characters at the end of the substitution. Embedded characters before the end of the output shall not be removed; however, they may be treated as field delimiters and eliminated during field splitting, depending on the value of IFS and quoting that is in effect. If the output contains any null bytes, the behavior is unspecified.

You will have to explicitly add a newline. Perhaps:

recipient="$user
"

There's really no reason to use a command substitution here. (Which is to say that $(echo ...) is almost always a silly thing to do.)

Upvotes: 4

Related Questions