comparação de strings e números no bash em instruções de teste?

comparação de strings e números no bash em instruções de teste?

Não tenho certeza sobre esta comparação que estou fazendo:

   if [ "$exit_status" -eq 0 ];then
   #some statements
   fi

esta forma correta de comparar números ou aspas torna a variável exit_statusuma string a ser comparada com 0. Não sei se isso pode falhar em algum cenário.

Responder1

Sim, está correto.

As citações em shells têm finalidades diferentes das de outros idiomas. Veresta respostapara mais detalhes.

No shell, aspas são usadas para evitar que o shell trate alguns caracteres de maneira especial e para evitar algumas operações que o shell executaria em alguns tipos de expansão (como neste caso a expansão de variável).

Normalmente, neste caso, você deseja "$exit_status"expandir para um argumento para o [comando que é o conteúdo dessa variável, então você precisa das aspas.

Responder2

[ "$exit_status" -eq 0 ]está correto se $exit_status contém apenas dígitos, e você também pode remover as aspas (desde que IFS não contenha dígitos).

Se x estiver vazio ou não definido, [ "$x" -eq 6 ]resulta em erro, mas [[ "$x" -eq 6 ]]não:

$ x=; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ unset x; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ x=; [[ "$x" -eq 6 ]]
$ unset x; [[ "$x" -eq 6 ]]
$ 

Operadores aritméticos eliminam espaços em branco:

$ [ '6 ' -eq $'\n\t6' ]; echo $?
0

Dentro de [[ os operandos dos operadores aritméticos são expressões aritméticas, então, por exemplo, [[ 4 -eq 2+2 ]]é verdadeiro. Os números que começam com 0 são tratados como números octais:

$ [[ 010 -eq 8 ]]; echo $?
0
$ [ 010 -eq 8 ]; echo $?
1

Costumo usar = / == mesmo para comparar números inteiros. = e == são equivalentes no bash dentro de [[ e [. == e [[ não são definidos pelo POSIX.

A divisão de palavras e a expansão do nome do caminho não são executadas dentro de [[. [[ $x = $y ]]trata y como um padrão, mas [[ $x = "$y" ]]trata y literalmente:

$ x=44; y='4*'
$ [[ $x = $y ]]; echo $?
0
$ [[ $x = "$y" ]]; echo $?
1

Responder3

Citar números é de pouca utilidade. Se o valor do parâmetro for um número, as aspas não mudam nada e, se não for, o if falhará de qualquer maneira. OK, não em todos os casos:

exit_status="a = a -o 0"; [ "$exit_status" -eq 0 ] # returns false
exit_status="a = a -o 0"; [ $exit_status -eq 0 ] # returns true

Isso se deve ao fato [de ser um comando integrado do bash, mas ainda assim um comando simples, enquanto [[é um comando composto que altera a análise da linha de comando.

informação relacionada