Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I echo "$" in a here-doc in bash?

For example, I want to have a file with the content on remote server like $ABC=home_dir.

$ ssh hostname sudo -s <<EOF
echo "$ABC=home_dir" > file
EOF

But it would be treated as a variable. How can I print a literal $?

share|improve this question
2  
you can use single quotes –  Rahul Patil Mar 19 '13 at 9:17
1  
That is a lot of indirection going on. Are you sure you can't create the file on the local host and then scp it? –  l0b0 Mar 19 '13 at 13:18
add comment

4 Answers

Escape the $

$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF

I do not know what your use case is but usually you want home_dir=$ABC instead of $ABC=home_dir.

share|improve this answer
2  
This solution will work, but is that realy what the OP wants? It appears to generate a shell script which when executed will store in "file" a string which will dereference ABC for the left-side of the asignment and likely end up storing =home_dir to the file? Of course I don't know what the use case is... –  Johan Mar 19 '13 at 10:35
    
This will cause a literal $ to be sent to the remote shell, but then that shell will expand $ABC before echoing the string to file. To write the literal $ to the file, you'll need another (escaped) backslash: echo "\\\$ABC=home_dir", so that the remote shell receives echo "\$ABC=home_dir". –  chepner Mar 24 '13 at 3:08
add comment

If you want to write a here-doc and you don't want ANY of the doc to be expanded or any special characters interpreted, you can quote the label with single quotes, like this:

$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF

However, your situation as described in your example is much more complex, because you're really sending this content through ssh, to a remote system, to be run by sudo which is also invoking a shell (and so that shell will expand the content as well). You're going to need more levels of quoting to get this right, but even with that it still won't work because sudo requires a terminal (so it can ask for a password) and you've redirected from stdin. Even using ssh -t won't help here.

Also I agree with Johan. It's not clear this is really what you want; note that it's not legal to assign a value to a shell variable reference, so if this file you're trying to create is supposed to be a shell script, it won't work as you've described it. Maybe if you back up a bit and describe what you really want to do, we can help more.

share|improve this answer
add comment

The cheapest way of escaping would be

$ ssh hostname sudo -s << \EOF
echo "$ABC=home_dir" > file
EOF
share|improve this answer
add comment

You save yourself a level of quoting by sending the string to a cat process on the remote end:

echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"

The single quotes protect the $ on the local end, and the string is never seen by the shell on the other because it is read directly by cat (via sudo), rather than being an argument to another shell command.

With your code, you would need an extra layer of escaping to protect the $:

$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF

You need to send a literal \$ to the remote host, so that the remote shell will write a literal $ to the file. You could also simplify this by quoting the here-doc marker:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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