Parece haver algum mal-entendido aqui sobre o Bash embutido true
e, mais especificamente, sobre como o Bash expande e interpreta expressões entre colchetes.
O código na resposta de Miku não tem absolutamente nada a ver com o embutido Bash true
, nem /bin/true
, nem qualquer outro sabor do true
comando. Nesse caso, true
nada mais é do que uma simples cadeia de caracteres e true
nunca é feita nenhuma chamada ao comando / builtin, nem pela atribuição da variável nem pela avaliação da expressão condicional.
O código a seguir é funcionalmente idêntico ao código na resposta do miku:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
A única diferença aqui é que os quatro caracteres comparados são 'y', 'e', 'a' e 'h' em vez de 't', 'r', 'u' e 'e'. É isso aí. Não é feita nenhuma tentativa de chamar um comando ou um nome interno yeah
, nem existe (no exemplo do miku) nenhum tipo de tratamento especial acontecendo quando o Bash analisa o token true
. É apenas uma string e completamente arbitrária.
Atualização (19/02/2014): Depois de seguir o link na resposta do miku, agora vejo de onde vem parte da confusão. A resposta de Miku usa colchetes simples, mas o trecho de código ao qual ele vincula não usa colchetes. É apenas:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Ambos os trechos de código se comportam da mesma maneira, mas os colchetes mudam completamente o que está acontecendo sob o capô.
Aqui está o que Bash está fazendo em cada caso:
Sem colchetes:
- Expanda a variável
$the_world_is_flat
para a sequência "true"
.
- Tente analisar a cadeia
"true"
como um comando.
- Encontre e execute o
true
comando (embutido ou /bin/true
, dependendo da versão do Bash).
- Compare o código de saída do
true
comando (que é sempre 0) com 0. Lembre-se de que na maioria dos shells, um código de saída 0 indica sucesso e qualquer outra coisa indica falha.
- Como o código de saída foi 0 (êxito), execute a cláusula
if
da instruçãothen
Suportes:
- Expanda a variável
$the_world_is_flat
para a sequência "true"
.
- Analisar a expressão condicional agora totalmente expandida, que é da forma
string1 = string2
. O =
operador é o operador de comparação de strings do bash . Assim...
- Faça uma comparação de cadeias em
"true"
e "true"
.
- Sim, as duas cadeias eram iguais, portanto o valor da condicional é verdadeiro.
- Execute a cláusula
if
da instrução then
.
O código sem colchetes funciona, porque o true
comando retorna um código de saída 0, que indica sucesso. O código entre colchetes funciona, porque o valor de $the_world_is_flat
é idêntico à string literal true
no lado direito do =
.
Apenas para esclarecer as questões, considere os dois trechos de código a seguir:
Este código (se executado com privilégios de root) irá reiniciar o seu computador:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Este código apenas imprime "Boa tentativa". O comando reboot não é chamado.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Atualização (14-04-2014) Para responder à pergunta nos comentários sobre a diferença entre =
e ==
: AFAIK, não há diferença. O ==
operador é um sinônimo específico do Bash =
e, até onde eu vi, eles funcionam exatamente da mesma forma em todos os contextos.
Note, no entanto, que eu estou falando especificamente sobre os =
e ==
operadores de comparação de string usado em qualquer [ ]
ou [[ ]]
testes. Não estou sugerindo isso =
e ==
são intercambiáveis em todos os lugares no bash.
Por exemplo, você obviamente não pode fazer a atribuição de variáveis ==
, como var=="foo"
(bem, tecnicamente, você pode fazer isso, mas o valor de var
será "=foo"
, porque Bash não está vendo um ==
operador aqui, está vendo um =
operador (de atribuição), seguido por o valor literal ="foo"
, que acaba de se tornar "=foo"
).
Além disso, embora =
e ==
são intercambiáveis, você deve ter em mente que a forma como esses testes trabalho não depende se você estiver usando-o dentro [ ]
ou [[ ]]
, e também sobre se ou não os operandos são cotados. Você pode ler mais sobre isso no Advanced Bash Scripting Guide: 7.3 Outros operadores de comparação (role para baixo até a discussão sobre =
e ==
).
true
efalse
no contexto da maioria dos trechos abaixo, são apenas strings simples, não obash built-ins
!!! Por favor, leia a resposta de Mike Holt abaixo. (Este é um exemplo onde um altamente votou e resposta aceita é IMHO confuso e sombras conteúdo perspicaz em menor votado respostas)