Cite uma variável na instrução "if" do shell script

9

por exemplo

if [ "$FOO" = "true" ]; then

vs

if [ $FOO = "true" ]; then

Qual é a diferença? Parece que as duas instruções também funcionam.

Ryan
fonte
No Bash, use colchetes duplos e você não precisa das aspas e obtém benefícios adicionais .
Pausado até novo aviso.
@DennisWilliamson Não é bem assim, você precisa de aspas no lado direito dos operadores (in) de igualdade e correspondência de padrões.
Gilles 'SO- stop be evil'
@ Gilles: Às vezes não. Para strings literais que contêm espaços ou para strings literais ou variáveis que contêm caracteres glob que deseja ser tomado literalmente , o lado direito deve ser citado: a='foo bar'; [[ $a == "foo bar" ]]. No entanto, uma variável que não contenha caracteres glob não precisa ser: [[ $a == $a ]]. A expansão do Word não é executada entre colchetes duplos. E para a correspondência de regex, o padrão no lado direito não deve ser citado ou ele vai ser tomado como string literal: [[ $a =~ .*oo.*r ]](o padrão deve ser em uma variável citou-un, no entanto, em vez disso ...
. Pausada até novo aviso
de ser incorporado literalmente como aqui). Para estilo glob padrão de correspondência, os personagens glob não deve ser citado, seja literal ou em uma variável: [[ $a == foo* ]]. Você pode fornecer exemplos adicionais de um requisito para citação além do meu exemplo de string literal?
Pausado até novo aviso.

Respostas:

6

Se o valor de $FOOfor uma única palavra que não contenha um caractere curinga \[*?, as duas serão idênticas.

Se $FOOnão estiver atribuído, estiver vazio ou mais de uma palavra (ou seja, contiver espaço em branco ou $IFS), a versão não citada será um erro de sintaxe. Se for a sequência correta de palavras (como 0 -eq 0 -o false), o resultado poderá ser arbitrário. Portanto, é uma boa prática sempre citar variáveis ​​em scripts de shell.

Aliás, "true"não precisa ser citado.

200_success
fonte
3

Para ilustrar quais problemas isso pode causar, aqui estão alguns exemplos.

Digamos que temos duas variáveis ​​como segue:

FOO="some value"
BAR="some value"

Agora temos duas variáveis ​​segurando exatamente a mesma string / valor. Se fizemos algumas declarações if para testar o resultado, no seu caso:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

Neste ponto, você receberá bash: [: too many arguments. O $ FOO não cotado possui agora três valores, a saber '[ , some , value'. [A palavra-chave test não sabe o que executar, pois espera que o primeiro ou o segundo argumento seja um operador.

Quando citamos "$ FOO", dizemos explicitamente ifpara observar os valores corretos onde não ocorre a divisão de palavras.

Outro exemplo:

my_file="A random file.txt"
  • fazer rm $my_filesignifica remover 'A' 'aleatório' 'arquivo.txt', o que torna três arquivos.
  • fazendo rm "$my_file"removerá "Um arquivo aleatório.txt", que cria um arquivo.

Espero não ter confundido você com esses exemplos.

Valentin Bajrami
fonte
0

Nesse caso específico, não há diferença.

No entanto, se $FOOcontiver um espaço ou alguns caracteres especiais, você terá um problema.

No "$FOO"caso, ele usará a variável no total, para fazer a partida isolar você do problema de espaço.

No entanto, se você usar $FOOe houver um caso especial, isso afetará a instrução if.

mdpc
fonte