Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Messy bash variable

Tags:

bash

awk

I'm writing a script to ssh in to a list of machines and compare a variable to another value.. I've run into a problem (I have a couple workarounds, but at this point I'm just wondering why this method isn't working).

VAR=`ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt"`

($i would be a hostname. The hosts are trusted, no password prompt is given)

Example of foo.txt:

foo:123456:abcdef
bar:789012:ghijkl
baz:345678:mnopqr

I'm assuming it's a problem with quotes, or \'s needed somewhere. I've tried several methods (different quoting, using $() instead of ``, etc) but can't seem to get it right. My script is working correctly using the following:

VAR=`ssh $i "grep bar /local/foo.txt" | awk -F: '{print \$2}'`

Like I said, just a curiousity, any response is appreciated.

Forgot to post what my output was: awk is spitting out the whole matched line, not the 2nd section. Playing with the quotes and \'s a bit I seemed to get an error about "{print " command not found etc, as if there was a new line in there somewhere.

like image 766
Kyle Avatar asked Mar 18 '10 18:03

Kyle


1 Answers

sshd gives your command to bash to execute, so it'll go through the bash interpreter on the remote side as well as the side you're executing the script on. Let's look at your command:

VAR=`ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt"`

You've properly escaped the $2 for your local machine so that the bash script you're executing does not interpret it. But all the quotes are being removed by the time it gets to awk (I'm not entirely sure why the internal quotes get removed) and it's executing this:

awk -F: /^bar/ {print $2} /local/foo.txt

bash on the remote side sees $2 and replaces it with an empty string, leaving you with this:

awk -F: /^bar/ {print } /local/foo.txt

That's why it prints the entire line. So how do you fix it? You can escape what bash on the remote side will be executing with a slash, like so:

VAR1=`ssh $i localhost "echo awk -F: '/^bar/ {print \\\$2}' /local/foo.txt"`

Also, you can just echo the command to see what bash is really executing for you to debug any further problems you come across:

VAR1=`ssh $i localhost "echo awk -F: '/^bar/ {print \$2}' /local/foo.txt"`
echo VAR1: $VAR1

Execute it and see this output and see right away that it has removed $2:
VAR1: awk -F: /^bar/ {print } /local/foo.txt
like image 96
indiv Avatar answered Sep 25 '22 23:09

indiv