Essas citações com escape em \"test\" me fazem pensar que há alguma confusão sobre as regras de citação do shell, porque o primeiro código funciona como pretendido e $STATUS == \"test\" não deveria (a menos que você tenha escrito STATUS='echo '"test"'' ou algo semelhante ).
Para esclarecer adequadamente essa confusão, é necessário explicar alguns conceitos de shell.
Citação
Em shells POSIX, a cotação é um dos mecanismos mais importantes. Infelizmente, também é um tópico muito confuso e, quando usado incorretamente, uma grande fonte de bugs e comportamentos estranhos em scripts.
As regras básicas são as seguintes:
-
Caractere de escape
\ : Preserva o valor literal do próximo caractere seguinte, com exceção de <newline> .
-
Aspas duplas
" : Preserva o valor literal de todos os caracteres entre aspas, com exceção de $ , ' , \ e, quando a expansão de histórico está ativada, ! .
-
Aspas simples
' : Preserva o valor literal de todos os caracteres dentro das aspas, sem exceções.
Substituição de comandos
A substituição de comandos permite que a saída de um comando substitua o comando em si. Sua sintaxe é $(command) ou 'command' , embora a primeira seja preferida.
Comando de teste
O comando test (também conhecido como [ em POSIX e [[ em shells como bash, ksh e zsh) permite usar várias expressões aritméticas e condicionais úteis. Por exemplo, ele pode verificar se um determinado arquivo regular existe e é legível, se duas sequências são iguais ou se um número é maior que outro.
Agora, analisando o código:
STATUS='echo "test"'
A substituição de comando aqui é inútil, já que poderia ter sido escrita como STATUS="test" . Observe que as aspas duplas não são impressas por echo , portanto STATUS contém test como seu valor.
if [ $STATUS == "test" ]; then
exit 0
fi
Aqui estão, pelo menos, 3 possíveis falhas:
- O
$STATUS sem aspas pode ser afetado pela divisão de palavras.
-
== é sintaxe não POSIX. Use = se você se importa com a portabilidade.
-
if e exit 0 são inúteis neste cenário, pois [ já faz o trabalho pretendido.
Além disso, observe que, como a linha de código anterior, as aspas duplas não são consideradas literalmente, portanto, o comando resultante (após a remoção da expansão e da cotação) é [ test = test ] , o que é verdadeiro.
Mas se sua meta fosse ter "test" como o valor de STATUS ,
STATUS=\"test\"
STATUS="\"test\""
STATUS='"test"'
são todas as atribuições válidas e
[ "$STATUS" = \"test\" ]
[ "$STATUS" = "\"test\"" ]
[ "$STATUS" = '"test"' ]
são todas expressões condicionais válidas.