Em qualquer Unix diferente daqueles que possuem sistemas de arquivos que não diferenciam maiúsculas de minúsculas (como macOS), a instrução if
if ! $flag; then
echo "No brackets: Flag is $flag"
fi
geraria a saída
bash: False: command not found
No brackets: Flag is False
No macOS, o erro não seria gerado, pois o comando False é o mesmo que o comando padrão (externo) false , devido à insensibilidade a maiúsculas e minúsculas do sistema de arquivos.
Em ambos os casos, o teste em ! $flag é verdadeiro (mas por motivos diferentes), então o texto é impresso. Na maioria dos Unices, ! $flag é true, pois ele executa o comando False , falha e a falha é negada. No macOS, ele executa o utilitário externo false , que retorna false, que é negado.
A segunda declaração if ,
if [ ! $flag ]; then
echo "With brackets: Flag is $flag"
fi
funciona da mesma maneira em qualquer Unix. Ele chama o utilitário [ , que é igual ao utilitário test (mas [ requer um ] correspondente como seu último operando), com os dois argumentos ! e False . Por padrão, test retornará um valor verdadeiro se o argumento de string tiver comprimento diferente de zero, o que ele tem, mas é negado pelo ! so test retorna false e o echo nunca é executado.
Para maior clareza, é melhor usar o teste -n para testar uma string não vazia:
if [ -n "$flag" ]; then ...
ou -z para testar uma string vazia:
if [ -z "$flag" ]; then ...
A citação das expansões de variáveis não é importante nesta parte específica do código, pois $flag se expande para uma única palavra que não é um padrão de globalização de nomes de arquivos. Em geral, no entanto, as expansões variáveis devem ser duplamente citadas para evitar a divisão de palavras e a globalização de nomes de arquivos.
Para uma discussão sobre [ vs. [[ , consulte
Relacionados:
-
man testno seu sistema ehelp testem qualquerbashshell. - Por que meu script de shell se sufoca em espaços em branco ou outros caracteres especiais?