Bash: compara duas strings com espaço

5

Eu estou tentando escrever um script bash que executa um comando e compara o resultado com outra 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

Como a string original está em duas linhas, faço eco em uma nova variável TEST. A nova variável tem a saída do comando em uma linha.

Aqui está a saída de depuração do Bash:

++ /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

Eu também tentei o seguinte teste:

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

A coisa é bash não é capaz de comparar as cordas é sempre falsa.

Alguma ideia?

EDITAR:

Aqui está a saída com a primeira resposta:

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

Ainda não está funcionando ON parece estranho na linha 3, mais no meu bash leva cor verde!

    
por Hugo 17.10.2013 / 11:58

2 respostas

5

Altere esta linha:

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

Para isso:

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

Detalhes

O problema é o uso de [[ .. ]] . A saída está mostrando a diferença. Seu valor que você está obtendo para $STATUS não é simplesmente "On Master". Provavelmente contém outros caracteres, que provavelmente não são imprimíveis, portanto não estão sendo vistos.

[[..]]

++ 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' ']'

O uso de colchetes duplos ( [[ .. ]] ) é discutido aqui no Bash Avançado do TLDP Páginas de script .

echo $ STATUS

Esta linha parece um pouco suspeita para mim também. Eu protegeria o conteúdo de $STATUS colocando-o entre aspas duplas também.

TEST='echo "$STATUS"'

Além disso, eu descartaria os back carrapatos ('...') e usaria a notação $( ... ) para executar este comando. Essa alteração é apenas uma prática recomendada e não faz parte do seu problema.

TEST=$(echo "$STATUS")

Caracteres de controle na saída (^ [[92mON ^ [[0m mestre)

Considerando que você está vendo esses caracteres de controle em sua saída ( ^[[92m & ^[[0m ), suspeito que o comando grep esteja introduzindo esses caracteres em sua saída no canal. Pode ser que grep seja aliases para sempre incluir a opção --color , eu temporariamente tente chamar o executável diretamente e passar todos os aliases que possam estar lá. Basta alterar o grep para isso, /bin/grep .

A presença deles é o que suspeitamos e é por isso que o texto estava sendo encapsulado quando você usou echo da variável $STATUS . Esses caracteres não podem ser impressos e mudam a cor do terminal para destacar as correspondências que grep encontrou.

A presença deles também explica por que o operador =~ não correspondeu também. Você estava tentando corresponder 'On Master' a '^[[92mON^[[0m Master' .

Por fim, a saída colorida com os caracteres de controle pode vir de outra ferramenta antes do grep . Eu precisaria ver a saída real de /root/setup_ha para confirmar isso, mas eu suspeitaria dessa ferramenta também ao produzir esses caracteres no fluxo de tubos.

Removendo os caracteres de controle

Eu encontrei este U & L Q & A intitulado: Programa que passa STDIN para STDOUT com códigos de cores removidos? .

Use um desses métodos para se livrar dos caracteres de controle.

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"
    
por 17.10.2013 / 16:21
0

Por padrão, o eco insere uma nova linha à direita. Não sei por que você está pegando o resultado do seu comando, armazenando-o em TESTE e tentando ecoar o valor TEST em STATUS.

Apenas compare o TEST.

    
por 17.10.2013 / 20:24

Tags