Bash Strings – How to Compare Two Strings with Space

bashstring

I am trying to write a bash script which run a command and compare the result with another string.

#!/bin/bash -x

STATUS=`/root/setup_ha show --password-file=/root/password | grep ">HA State" | awk '{print $3}' |  cut -c 2-`

TEST=`echo $STATUS`
if [[ "$TEST" == "ON Master" ]];
then echo CLUSTER CRITICAL
else
  echo CLUSTER OK MASTER
fi

As the Original string is on two lines, I echo it in a new variable TEST.
The New variable have the output of the command on one line.

Here is the Bash debug output :

++ /root/setup_ha show --password-file=/root/password
++ grep '>HA State'
++ awk '{print $3}'
++ cut -c 2-
+ STATUS='ON
Master'
++ echo 'ON' Master
+ TEST='ON Master'
+ [[ ON Master == \O\N\ \M\a\s\t\e\r ]]
+ echo CLUSTER OK MASTER
CLUSTER OK MASTER

I also tried the following test :

if [[ "$TEST" =~ "ON Master" ]]

The thing is bash is not able to compare the strings it is always false.

Any idea ?

EDIT :

Here is the output with the first answer :

+ STATUS='ON
Master'
++ echo 'ON' Master
+ TEST='ON Master'
+ '[' 'ON Master' == 'ON Master' ']'
+ echo CLUSTER OK MASTER
CLUSTER OK MASTER

Still not working ON seems weird on line 3, plus in my bash it takes green color !

Best Answer

Change this line:

if [[ "$TEST" == "ON Master" ]];

To this:

if [ "$TEST" == "ON Master" ];

Details

The issue is the use of [[ .. ]]. The output is showing you the difference. Your value that you're getting for $STATUS is not simply "On Master". It most likely contains other characters, that are most likely not printable so are not being seen.

[[ .. ]]

++ echo On Master
+ TEST='On Master'
+ [[ On Master == \O\N\ \M\a\s\t\e\r ]]

[ .. ]

++ echo On Master
+ TEST='On Master'
+ '[' 'On Master' == 'ON Master' ']'

The use of double square brackets ([[ .. ]]) is discussed here on the TLDP Advanced Bash Scripting pages.

echo $STATUS

This line seems a little suspicious to me as well. I'd protect the contents of $STATUS by wrapping it in double quotes as well.

TEST=`echo "$STATUS"`

Also I'd drop the back ticks ( `...` ) and use the $( ... ) notation instead for executing this command. This change is just a best practice and isn't part of your issue though.

TEST=$(echo "$STATUS")

Control characters in output (^[[92mON^[[0m Master)

Given you're seeing these control characters in your output (^[[92m & ^[[0m) I'm suspicious that the grep command is introducing these into your output in the pipe. It may be that grep is aliases to always include the --color switch, I'd temporarily try calling the executable directly, and by pass any aliases that may be there. Just change the grep to this, /bin/grep.

The presence of these is what we suspected and is why the text was wrapping when you echo the variable $STATUS. These characters are unprintable, and change the color of the terminal to highlight matches that grep has found.

The presence of these also explains why the =~ operator didn't match too. You were trying to match 'On Master' with '^[[92mON^[[0m Master'.

Lastly the colored output with the control characters may be coming from another tool before the grep. I would need to see the actual output from /root/setup_ha to confirm this, but I would be suspicious of that tool as well in producing these characters in the pipe stream.

Stripping the control characters

I found this U&L Q&A titled: Program that passes STDIN to STDOUT with color codes stripped?.

Use either of these methods to get rid of the control characters.

Perl

$ cmd-with-colored-output | perl -pe 's/\e\[?.*?[\@-~]//g'

Sed

$ cmd-with-colored-output | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"