28

I am trying to execute a single command over ssh that contains `sub-code` or $(sub-code) (I use it all the time but I don't know the official name for that) to be executed first, but on the target server.

For the sake of argument, let's say this is the command I want to use. Ofcourse this can be done with hostname, but this is just a simplified example that contains all the formatting wizardry I want to use.

echo `uname -a | awk '{print $2}'`

No problem. But how do you escape this properly to send it over ssh in a single command? The following is wrong, because it lets the server reply your local hostname. The sub-code is executed locally:

ssh myServer echo `uname -a | awk '{print $2}'`

But any escape-ishness that comes to mind doesn't work:

$ ssh myServer echo \`uname -a | awk '{print $2}'\`
awk: cmd. line:1: {print $2}`
awk: cmd. line:1:           ^ invalid char '`' in expression
$ ssh myServer echo \$(uname -a | awk '{print $2}')
bash: syntax error near unexpected token `('
$ ssh myServer echo \$\(uname -a | awk '{print $2}')
bash: syntax error near unexpected token `)'
$ ssh myServer echo \$\(uname -a | awk '{print $2}'\)
awk: cmd. line:1: {print $2})
awk: cmd. line:1:           ^ syntax error
bash: -c: line 0: unexpected EOF while looking for matching `)'
bash: -c: line 1: syntax error: unexpected end of file

I would like an answer that includes using properly escaped ` or $() because I'd like to know if it's possible.echo` could be something more complicated.

2
  • 1
    why echo `command`? why not command? Commented Feb 5, 2013 at 13:26
  • 1
    @anishsane because he wants to see how to pass a backtick or a $( through ssh to a remote server Commented Feb 5, 2013 at 13:32

6 Answers 6

73

Try this

ssh myServer "uname -a | awk '{print \$2}' "

Use the double quotes " in order to group the commands you will execute remotely.

You also need to escape the $ in the $2 argument, so that it is not calculated locally, but passed on to awk remotely.

Edit:

If you want to include the $( ), you again have to escape the $ symbol, like this:

ssh myServer "echo \$(uname -a | awk '{print \$2}') "

You can also escape the backtick `, like this:

ssh myServer "echo \`uname -a | awk '{print \$2}'\` "
Sign up to request clarification or add additional context in comments.

3 Comments

@Redsandro I think I figured out how to escape the $( and the backtick on ssh. Just updated my answer...
If you execute in sub-command like res=`ls | awk '{print \\$2}'`, we need two escape here.
Yeah I was trying sshpass to execute /proc/loadavg on remote server and using awk to filter the result. Thanks for the answer. The escape sequence did the trick!. Thanks
10

It is better to use a heredoc with ssh to avoid escaping quotes everywhere in a more complex command:

ssh -T myServer <<-'EOF'
uname -a | awk '{print $2}'
exit
EOF

Comments

7

Just some additional note:

In my case, the escape of the $ doesn't help:

ts1350:> ssh sysadm@node "grep feature features.txt| awk '{print $6}' "
Password: 
A  feature   -name  ue_trace_mme    | off
ts1350:> ssh sysadm@node "grep feature features.txt| awk '{print \$6}' "
Password: 
awk: cmd. line:1: {print \}
awk: cmd. line:1:        ^ backslash not last character on line
awk: cmd. line:1: {print \}
awk: cmd. line:1:        ^ syntax error
ts1350:> ssh sysadm@node "grep feature features.txt| awk '{print \\$6}' "
Password: 
awk: cmd. line:1: {print \\}
awk: cmd. line:1:        ^ backslash not last character on line
awk: cmd. line:1: {print \\}
awk: cmd. line:1:        ^ syntax error

While add a space between $ and the number works:

Fri Oct  4 14:49:28 CEST 2019
ts1350:> ssh sysadm@node "grep feature features.txt| awk '{print $ 6}' "
Password: 
off

Hope this secodnary way help someone like me.

Thanks to @dave in his answer: How to print a specific column with awk on a remote ssh session?

1 Comment

While add a space between $ and the number works, this is amazing, thank you very much. I tried \' \$, almost everything, still does not work, frustrated.
5

What about piping the output of the command and run awk locally?

ssh yourhost uname -a | awk '{ print $2 } '

1 Comment

Thanks, this works in certain cases. However, for more versatility, user000001's answer does exactly what I want. :)
4

The workaround is to create an sh file with the command then pass it to ssh command:

test.sh

echo `uname -a | awk '{print $2}'`

and command:

ssh myServer 'bash -s' < test.sh

UPDATE:

The command without quotes works fine as well:

ssh myServer uname -a | awk '{print $2}'

5 Comments

@"The command without quotes works fine as well:" the awk being executed is local awk, not on the remote system.
Yes, commands from all 3 questions run the right part (after the pipe) locally. So the only solution is to save the command in the script.
Thanks, this works. Upvoted. But user000001 does exactly what I want in a single command, I've accepted that one. :)
"So the only solution is to save the command in the script" : I object the "only" word. probably you meant "easiest".
sorry, I mean answers. I've tested the last command of user000001 and it works on the remote server so I was wrong.
2

If you are trying to get the hostname, use:

ssh myServer "uname -n"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.