0

I have the following script:

#!/bin/bash
if [ "$1" == "" ]
then
        echo "To start monitor, please provide the server ip:"
        read STRIP
else
        STRIP=$1
fi

ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print $5 " " $1 " " $2}'"

so if I type this on terminal:

./my_script.sh 192.168.5.210

It should SSH to my portal 209 and then SSH to 210 and get its hard disk info. The problem is it is not working as expected, instead it just output 5 rows like this:

192.1680.50.21
192.1680.50.21
192.1680.50.21
192.1680.50.21
192.1680.50.21

I tried to manually set the IP as variable in script or echo the value of the argument and it works fine?

for example this works fine:

STRIP=192.168.5.210
ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print $5 " " $1 " " $2}'"

But if I pass an argument without using it I get 5 blank row though

1 Answer 1

1

Quotes don't nest. You're trying to pass ssh the remote command as a double-quoted string containing a single-quoted argument to awk, and within that argument several double-quoted strings. But the shell sees each of those double-quotes as the start or end of a double-quoted string, which makes quite a mess.

Specifically, when you use "df -khP | column -t | awk '{print $5 " " $1 " " $2}'" in the list of arguments to ssh, it gets parsed into several separate quoted strings. The first is "df -khP | column -t | awk '{print $5 ", and since $variable substitution is done inside double-quoted strings, and the script didn't get 5 arguments, the $5 part gets replaced by nothing, giving "df -khP | column -t | awk '{print ". The next is " $1 ", which gets expanded to " 192.168.5.210 " (because that's the first argument to the script). Finally, there's " $2}'", which expands into " }'" because there's no second argument. ssh then pastes these together with spaces between, giving `df -khP | column -t | awk '{print 192.168.5.210 }' as the command being executed. Not at all what you wanted.

In order to get it to work right, you need to escape (with backslashes) certain characters within what's supposed to be a single long double-quoted string. Specifically, all double-quotes (to keep them from ending the quoted string) and dollar signs (to keep them from being expanded as parameters or whatever). Any backquotes or backslashes would also need to be escaped if there were any. Thus, this is the command you want:

ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print \$5 \" \" \$1 \" \" \$2}'"

BTW, if I understand it right, the reason awk prints what it does is that it's parsing 192.168.5.210 as three real numbers, 192.168, .5, and .210, and printing them (with leading zeroes added where needed and trailing zeroes left off as irrelevant) as "192.168", "0.5", and "0.21". But it doesn't print spaces between them, so it comes out as "192.1680.50.21".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .