Parece haver algum mal-entendido aqui sobre o Bash embutido truee, 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 truecomando. Nesse caso, truenada mais é do que uma simples cadeia de caracteres e truenunca é 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_flatpara a sequência "true".
- Tente analisar a cadeia
"true"como um comando.
- Encontre e execute o
truecomando (embutido ou /bin/true, dependendo da versão do Bash).
- Compare o código de saída do
truecomando (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
ifda instruçãothen
Suportes:
- Expanda a variável
$the_world_is_flatpara 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
ifda instrução then.
O código sem colchetes funciona, porque o truecomando 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 trueno 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 varserá "=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 ==).
trueefalseno 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)