6

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 !

Hugo
  • 2,439
  • 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
  • I got a | before ON and Master. I removed it with cut – Hugo Oct 17 '13 at 14:44
  • You should use =, not ==. – l0b0 Oct 21 '13 at 13:17
  • =~ is for regular expressions, and works exactly like = when used with a quoted regular expression. You'd have to use =~ ON\ Master. – l0b0 Oct 21 '13 at 13:18

2 Answers2

8

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"
slm
  • 369,824
  • 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
  • 1
    [[ "$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 'SO- stop being evil' Oct 17 '13 at 21:46
  • @Gilles - yeah I moved past that, something is up with the output coming from the command to populate the $STATUS variable Waiting to hear back from the OP. – slm Oct 17 '13 at 21:48
  • @Gilles - seems like something up with the output of echo. Notice this in his output: ++ echo 'ON' Master. Seems odd that there would be single quotes around the word ON. He's echoing that variable which includes spaces as a bare string. – slm Oct 17 '13 at 21:52
  • @slm I tried with TEST=$(echo "$STATUS"), but still the same issue. I used echo for removing the carrier return between ON and Master. But it seems to be there anyway. The weird thing is that even with =~ it doesn't match – Hugo Oct 18 '13 at 07:00
  • @slm Ok I found what is "wrong" in my output command. I redirected the output to a tmp file : here is what I get : "^[[92mON^[[0m Master" Any idea how can I deal with those weird characters ? – Hugo Oct 21 '13 at 10:16
  • @Hugo - see update, let me know if that helps. – slm Oct 21 '13 at 12:44
  • @slm I just try. This is not coming from grep, but coming from the original command showing the result in color. Have you got any idea on how I can grab the result without color code ? thanks for the help ! – Hugo Oct 21 '13 at 13:17
  • @Hugo - you can use one of the methods laid out here: http://unix.stackexchange.com/questions/4527/program-that-passes-stdin-to-stdout-with-color-codes-stripped. I would use either the Perl or Sed solution! – slm Oct 21 '13 at 13:25
  • the perl solution did it thank you so much ! – Hugo Oct 22 '13 at 17:36
  • @Hugo - glad it did the trick. If you get a chance please consider upvoting my answer as well. 8-) – slm Oct 22 '13 at 17:38
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.

tdk2fe
  • 390
  • 1
  • 6