Chad Johnson
Chad Johnson

Reputation: 21905

Pipe string with newline to command in Bash

I am trying to pass in a string containing a newline to a PHP script via Bash.

#!/bin/bash

REPOS="$1"
REV="$2"

message=$(svnlook log $REPOS -r $REV)
changed=$(svnlook changed $REPOS -r $REV)

/usr/bin/php -q /home/chad/www/mantis.localhost/scripts/checkin.php <<< "${message}\n${changed}"

When I do this, I see the literal "\n" rather than the escaped newline:

blah blah issue 0000002.\nU app/controllers/application_controller.rb

How can I translate '\n' to a literal newline?

By the way: What does <<< do in Bash? I know < passes in a file...

Upvotes: 20

Views: 39675

Answers (4)

Andre Holzner
Andre Holzner

Reputation: 18695

In order to avoid interpretation of potential escape sequences in ${message} and ${changed}, try concatenating the strings in a subshell (a newline is appended after each echo unless you specify the -n option):

( echo "${message}" ; echo "${changed}" ) | /usr/bin/php -q /home/chad/www/mantis.localhost/scripts/checkin.php

The parentheses execute the commands in a subshell (if no parentheses were given, only the output of the second echo would be piped into your PHP program).

Upvotes: 1

Andre Holzner
Andre Holzner

Reputation: 18695

Try

echo -e "${message}\n${changed}" | /usr/bin/php -q /home/chad/www/mantis.localhost/scripts/checkin.php

Where -e enables interpretation of backslash escapes (according to man echo).

Note that this will also interpret backslash escapes which you potentially have in ${message} and in ${changed}.


From the Bash manual:

Here Strings

A variant of here documents, the format is:

<<<word

The word is expanded and supplied to the command on its standard input.

So I'd say

the_cmd <<< word

is equivalent to

echo word | the_cmd

Upvotes: 27

gavenkoa
gavenkoa

Reputation: 48923

It is better to use here-document syntax:

cat <<EOF
copy $VAR1 $VAR2
del $VAR1
EOF

You can use magical Bash $'\n' with here-word:

cat <<< "copy $VAR1 $VAR2"$'\n'"del $VAR1"

or pipe with echo:

{ echo copy $VAR1 $VAR2; echo del $VAR1; } | cat

or with printf:

printf "copy %s %s\ndel %s" "$VAR1" "$VAR2" "$VAR1" | cat

Test it:

env VAR1=1 VAR2=2 printf "copy %s %s\ndel %s" "$VAR1" "$VAR2" "$VAR1" | cat

Upvotes: 2

Dennis Williamson
Dennis Williamson

Reputation: 360665

newline=$'\n'
... <<< "${message}${newline}${changed}"

The <<< is called a "here string". It's a one line version of the "here doc" that doesn't require a delimiter such as "EOF". This is a here document version:

... <<EOF
${message}${newline}${changed}
EOF

Upvotes: 5

Related Questions