1

I'm trying to compare two variables inside an if condition:

#!/bin/bash
Jump="/home/Lists/srv"
S=`echo "$1" | perl -ne 'print lc'`
J1=`grep $S $Jump |awk '{print $1}'`
grep $S $Jump >> /dev/null
if [ $? = 0 ]
 then
   if [ "$S" == "$J1" ]
   then
     echo "$S" is equal to "$J1" :
     ssh -qt $S "$2"
   else
     echo "$S" is not equal to "$J1"
     ssh -qt $J1 "ssh -qt $S $2"
   fi
  else 
    ssh -qt $S "$2"
  fi

Whenever I try to execute it always goes to else condition. and executes echo "$S" is not equal to "$J1"

I'm executing this script as ./test.sh followed by a server name for ex:

./test.sh hostname1

It should then lower the case and put it in variable S, and search for $S in the file Jump="/home/Lists/srv". If it finds there it should grep the first column and put it in another variable J1. Now, if value of S and J1 are similar, then it should ssh to $S else (1st) it should first ssh to $J1 and then ssh to $S. Else (2nd) if it doesn't find $S in Jump file it should directly ssh $S.

While I'm executing it directly goes to 1st else condition. even if $S and $J1 are similar.

  • Yes I'm actually using it like that a=hello and b=hi. that was a typing miss. There is no space and no $ while declaring variables. Please advice... – Vikas Thakur Jan 14 '17 at 10:35
  • Well, the strings hello and hi are not equal. Also see unix.stackexchange.com/questions/72039/… – Kusalananda Jan 14 '17 at 10:38
  • 2
    For the updated question: You will have to explain how you call this script and what you expect to happen. – Kusalananda Jan 14 '17 at 11:05
  • I'm executing this script as ./test.sh followed by a server name for ex: ./test.sh hostname1 – Vikas Thakur Jan 14 '17 at 11:16
  • I'm executing this script as ./test.sh followed by a server name for ex: ./test.sh hostname1 It should then lower the case and put it in variable 'S', and search for 'S' in the file Jump="/home/Lists/srv" if it finds there it should grep the first column and put it in another variable J1. Now, if value of 'S' and 'J1' are similar, then it should ssh to 'S' else (1st) it should first ssh to J1 and then ssh to S. Else (2nd) if it doesn;t find 'S' in Jump file it should directly ssh 'S'. While Im executing it directly goes to 1st else condition. even if S and J1 are similar – Vikas Thakur Jan 14 '17 at 11:23
3

From your description of what you're trying to achieve, the following may be a script that does that:

#!/bin/bash

server="${1,,}"

jumphost="$( awk -vs="$server" '$0 ~ s { print $1; exit }' "/home/Lists/srv" )"

if [[ -z "$jumphost" ]] || [[ "$jumphost" == "$server" ]]; then
    ssh -qt "$server" "$2"
else
    ssh -qt "$jumphost" "ssh -qt \"$server\" \"$2\""
fi

The parameter expansion ${1,,} will lower-case the value of $1. For older versions of bash, use the following instead:

server="$( printf '%s' "$1" | tr 'A-Z' 'a-z' )"

The jumphost variable will be set to whatever is in the first column of the first line in the file /home/Lists/srv matching the name of the server. Note that this only picks out the first match in the file and that the match is taking the whole line into consideration.

If the match should be only against the second column, change $0 to $2 in the Awk script.

If $jumphost is empty, or if it's the same as $server, then the first branch will be taken, otherwise the second.

An explanation of the Awk script was requested:

jumphost="$( awk -vs="$server" '$0 ~ s { print $1; exit }'

With -v one sets an Awk variable to a specific value. In the command above, we set the Awk variable s to the value of $server. This variable is then available within the Awk script.

In the Awk script,

$0 ~ s { print $1; exit }

the code within { ... } will be executed whenever the condition $0 ~ s is true. The condition $0 ~ s means "$0 matches (the regular expression) s". The variable s is what we gave the value of $server just before, and $0 is the contents of the current record (line) that Awk has just read. So in short, this finds a line in the file that contains the server name.

To force an exact match on the second column (for example), one could instead use $2 == s as the condition.

The code in { ... } will print $1, which is the first field (column) of $0 (the line), before it exits the script. I'm choosing to exit so that we don't end up matching more than a single line. If the user specifies a too vague value for $server, we run the risk of matching multiple lines otherwise.

Finally, the value outputted by Awk will be assigned to the shell variable jumphost through $( ... ), which is roughly the same as `...`.

  • it fails with : ./test.sh: line 2: ${1,,}: bad substitution awk: syntax error near line 1 awk: bailing out near line 1 – Vikas Thakur Jan 14 '17 at 12:12
  • What version of bash are you using. What is the output of /bin/bash --version? – Kusalananda Jan 14 '17 at 12:56
  • It's GNU bash, version 3.2.52(1)-release (sparc-sun-solaris2.10) Copyright (C) 2007 Free Software Foundation, Inc. – Vikas Thakur Jan 14 '17 at 13:05
  • @VikasThakur Use server="$( printf '%s' "$1" | tr 'A-Z' 'a-z' )" instead of server="${1,,}" in that case. I have updated the answer with this information. – Kusalananda Jan 14 '17 at 13:17
  • @VikasThakur On Solaris, you might also want to use nawk or /usr/xpg4/bin/awk instead of just awk. – Kusalananda Jan 14 '17 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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