5

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 !

  • How about if you use if [ "$TEST" = "ON Master" ]; then ... instead? (What version of Bash? I can't reproduce your problem on Bash 3.2.48 or 4.1.5.) – 200_success Oct 17 '13 at 10:25
  • 1
    works here (that is: if i set STATUS='ON Master' the script prints "CLUSTER CRITICAL"); most likely your /root/setup_ha returns something that weird... – umläute Oct 17 '13 at 10:25
  • @Hugo , you don't need to echo variable again you can directly use if [[ "${STATUS}" == "ON Master" ]]; – Rahul Patil Oct 17 '13 at 11:13
  • I am running Bash 4.1.2(1)-release. Even with [ "$TEST" = "ON Master" ]; it doesn't work always Cluster OK. Maybe the output of the command is weird, But I can't see what is wrong... If I set TEST="ON Master" it works so I have an issue with the command output – Hugo Oct 17 '13 at 12:29
  • by the way, by | grep ">HA State" | awk '{print $3}' | cut -c 2- you mean awk '{if(/>HA State/) print $3;}'? (I don't really see what should the cut do, but it definitely is possible with awk. – peterph Oct 17 '13 at 13:21
5

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"
  • I tried but I still get the issue : + STATUS='ON Master' ++ echo 'ON' Master + TEST='ON Master' + '[' 'ON Master' == 'ON Master' ']' + echo CLUSTER OK MASTER . The funny thing is "ON" appear in green in my shell, it seems like special. You can see that echo put 'ON' and then Master. What do you think ? – Hugo Oct 17 '13 at 14:39
  • @Hugo - can you paste this into your Q at the bottom? I can't read code that easily when pasted into the comment boxes. – slm Oct 17 '13 at 14:56
  • Ok I added to the end of the question. – Hugo Oct 17 '13 at 16:37
  • @Hugo - can you change this line? TEST=`echo "$STATUS"` Notice I added double quotes around $STATUS. – slm Oct 17 '13 at 16:57
  • [[ "$TEST" == "ON Master" ]] is exactly equivalent to [ "$TEST" == "ON Master" ]. Whatever is going on (I haven't dug in yet), that's not it. – Gilles Oct 17 '13 at 21:46
0

By default, echo inserts a trailing newline. I'm not sure why you are taking the result of your command, storing it in TEST, and then trying to echo the value TEST into STATUS.

Just compare TEST.

  • echo inserts a trailing newline, but the command substitution eats it up. – Gilles Oct 17 '13 at 23:44
  • I used echo at the beginning because STATUS return ON and Master on another line wanted to make it on one line. Echo $TEST was returning what I was expected. But it doesn't help. – Hugo Oct 18 '13 at 7:03

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.