O Bash não tem o conceito de valores Boolean. Existem strings e números, e arrays de strings ou de números. Então, como é que os comandos condicionais lidam com verdadeiro e falso?
Os comandos produzem um estado de saída quando terminam. Um estado de saída é um número inteiro entre 0 e 255, inclusive. O Bash considera que um estado de saída zero representa sucesso. Qualquer outro estado de saída representa falha.
Isto aplica-se a todos os comandos, incluindo comandos internos do Bash, palavras-chave e funções.
A sintaxe básica do comando if é
if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi
Começa com if; os comandos da condição são separados dos comandos de "sucesso" por then; e termina com fi.
A cláusula else é opcional.
CONDITIONAL_COMMANDS pode ser um único comando ou pode ser uma lista de comandos.
Os CONDITIONAL_COMMANDS são executados e
É possível indicar ramificações em cascata com elif
if CONDITIONAL_COMMANDS
then TRUE_COMMANDS
elif CONDITIONAL_COMMANDS_2
then TRUE_COMMANDS_2
# more elif branches ...
else FALSE_COMMANDS
fi
É preciso um ponto e vírgula ou uma mudança de linha antes das palavras then, elif, else e fi.
Para reforçar: é o estado de saída dos comandos condicionais que controla o fluxo.
Por exemplo, o grep devolve 0 se encontrar uma correspondência e 1 se não encontrar nenhuma.
A opção -q suprime a saída, produzindo apenas o estado de saída.
if grep -q "my pattern" my_file; then echo "the pattern is found in the file"; fi
Não há sintaxe especial em torno dos CONDITIONAL_COMMANDS. Podes estar habituado a ver condicionais assim:
if [ "$password" = "secure" ]; then
echo "Welcome!"
fi
O [ não é sintaxe especial.
É um comando que avalia a expressão condicional e termina com um estado de sucesso ou de falha.
Como em todos os comandos, é obrigatório haver espaço em branco entre ele e os seus argumentos.
Na verdade, o [ é um sinónimo do comando test.
São exatamente iguais, exceto que o último argumento do [ tem de ser ].
Dentro de [ e ], escreves uma expressão condicional.
Algumas expressões condicionais típicas são:
[ -f "$filename" ] # file operations
[ "$string1" = "$string2" ] # string comparisons
[ "$num1" -eq "$num2" ] # arithmetic comparisons
Há muitas mais operações disponíveis; estão listadas na secção Expressões condicionais do Bash do manual.
Nos exemplos acima, repara que todas as variáveis estão entre aspas.
Os comandos test e [ são comandos simples, em que os argumentos estão sujeitos à divisão de palavras e à expansão de nomes de ficheiros como qualquer outro comando.
Isto é importante salientar porque as expressões condicionais são avaliadas de forma diferente consoante quantos argumentos forneces:
[ -z "$name" ]) ou um ! (que nega o estado do teste de 1 argumento)Podes obter resultados inesperados se te esqueceres de colocar as aspas:
str=""
# this prints "empty"
if [ -n "$str" ]; then echo "not empty"; else echo "empty"; fi
# leaving the variable unquoted results in incorrect "not empty" output
if [ -n $str ]; then echo "not empty"; else echo "empty"; fi
A construção condicional [[...]] não é um comando, é uma palavra-chave.
Isto significa que, embora seja tratada como qualquer outro comando, tem regras de análise sintática especiais.
O que [[ tem de especial é que as variáveis expandidas dentro dele não estão sujeitas à divisão de palavras nem à expansão de nomes de ficheiros.
Isto significa que este comando funciona como esperas, mesmo sem aspas.
if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi
O [[ suporta todas as expressões condicionais que o test e o [ conseguem tratar.
Além disso, o [[ oferece
=~,== e != funcionam como operadores de correspondência de padrões glob,&& e || como operadores lógicos (regra de análise sintática especial),< e > como operadores "simples" de comparação de strings (regra de análise sintática especial: como são símbolos de redirecionamento, no [ têm de ser escapados).É amplamente aceite que estas funcionalidades especiais trazem tantas vantagens que se deve usar o [[ em exclusivo.
(Por exemplo, o Google Shell Style Guide.)
O case é outro comando de fluxo de controlo.
É semelhante a uma instrução "switch" noutras linguagens.
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
A WORD é comparada com cada PATTERN. Quando um corresponde, os COMMANDS são executados.
read -p "Guess the secret word: " word
case "$word" in
secret) echo "Yes, you guessed it!" ;;
??????) echo "That's the right number of letters." ;;
s*) echo "You guessed the first letter." ;;
*) echo "Not even close! Try again." ;;
esac
Cada cláusula COMMANDS tem de terminar com dois pontos e vírgulas, ;;.