<Anterior | Conteúdo | Próxima>
Combinando Expressões
Também é possível combinar expressões para criar avaliações mais complexas. As expressões são combinadas usando operadores lógicos. Vimos isso no Capítulo 17, quando aprendemos sobre o find comando. Existem três operações lógicas para teste e [[]]. Eles são AND, OR e NOT. teste e [[]] use diferentes operadores para representar essas operações:
Tabela 27-4: Operadores lógicos
Divisão de test [[]] e (())
Divisão de test [[]] e (())
E -uma &&
OR -o ||
NÃO ! !
Aqui está um exemplo de uma operação AND. O script a seguir determina se um número inteiro está dentro de uma faixa de valores:
#! / Bin / bash
# test-integer3: determine se um inteiro está dentro de um
# intervalo de valores especificado.
MIN_VAL = 1 MAX_VAL = 100
INT = 50
#! / Bin / bash
# test-integer3: determine se um inteiro está dentro de um
# intervalo de valores especificado.
MIN_VAL = 1 MAX_VAL = 100
INT = 50
if [["$ INT" = ~ ^ -? [0-9] + $]]; então
if [[INT -ge MIN_VAL && INT -le MAX_VAL]]; então echo "$ INT está entre $ MIN_VAL e $ MAX_VAL."
outro
echo "$ INT está fora do intervalo."
fi mais
echo "INT não é um número inteiro." > & 2 saída 1
fi
if [["$ INT" = ~ ^ -? [0-9] + $]]; então
if [[INT -ge MIN_VAL && INT -le MAX_VAL]]; então echo "$ INT está entre $ MIN_VAL e $ MAX_VAL."
outro
echo "$ INT está fora do intervalo."
fi mais
echo "INT não é um número inteiro." > & 2 saída 1
fi
Neste script, determinamos se o valor do inteiro INT encontra-se entre os valores de MIN_VAL e MAX_VAL. Isso é realizado por um único uso de [[]], que inclui duas expressões separadas por && operador. Também poderíamos ter codificado isso usando teste:
if [ $ INT -ge $ MIN_VAL -a $ INT -le $ MAX_VAL ]; então echo "$ INT está entre $ MIN_VAL e $ MAX_VAL."
outro
echo "$ INT está fora do intervalo."
fi
if [ $ INT -ge $ MIN_VAL -a $ INT -le $ MAX_VAL ]; então echo "$ INT está entre $ MIN_VAL e $ MAX_VAL."
outro
echo "$ INT está fora do intervalo."
fi
O ! operador de negação inverte o resultado de uma expressão. Retorna verdadeiro se uma expressão for falsa e retorna falso se uma expressão for verdadeira. No script a seguir, modificamos a lógica de nossa avaliação para encontrar valores de INT que estão fora do intervalo especificado:
#! / Bin / bash
# test-integer4: determine se um inteiro está fora de um
# intervalo de valores especificado.
MIN_VAL = 1 MAX_VAL = 100
INT = 50
if [["$ INT" = ~ ^ -? [0-9] + $]]; então
E se [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL)]]; então echo "$ INT está fora de $ MIN_VAL para $ MAX_VAL."
outro
echo "$ INT está dentro do intervalo."
#! / Bin / bash
# test-integer4: determine se um inteiro está fora de um
# intervalo de valores especificado.
MIN_VAL = 1 MAX_VAL = 100
INT = 50
if [["$ INT" = ~ ^ -? [0-9] + $]]; então
E se [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL)]]; então echo "$ INT está fora de $ MIN_VAL para $ MAX_VAL."
outro
echo "$ INT está dentro do intervalo."
echo "INT não é um número inteiro." > & 2 saída 1
fi
echo "INT não é um número inteiro." > & 2 saída 1
fi
Também incluímos parênteses ao redor da expressão, para agrupamento. Se estes não fossem incluídos, a negação se aplicaria apenas à primeira expressão e não à combinação das duas. Codificando isso com teste seria feito desta forma:
E se [ ! \ ($ INT -ge $ MIN_VAL -a $ INT -le $ MAX_VAL \)]; então echo "$ INT está fora de $ MIN_VAL para $ MAX_VAL."
outro
echo "$ INT está dentro do intervalo."
fi
E se [ ! \ ($ INT -ge $ MIN_VAL -a $ INT -le $ MAX_VAL \)]; então echo "$ INT está fora de $ MIN_VAL para $ MAX_VAL."
outro
echo "$ INT está dentro do intervalo."
fi
Uma vez que todas as expressões e operadores usados por teste são tratados como argumentos de comando pelo shell (ao contrário [[]] e (()) ), caracteres que têm um significado especial para bater, como <, >, ( e ), deve estar entre aspas ou com escape.
Vendo isso teste e [[]] fazer mais ou menos a mesma coisa, o que é preferível? teste é tradicional (e parte do POSIX), enquanto [[]] é específico para bater. É importante saber como usar teste, uma vez que é muito usado, mas [[]] é claramente mais útil e mais fácil de codificar, por isso é preferível para scripts modernos.
Portabilidade é o Hobgoblin das Pequenas Mentes
Se você conversar com pessoas “reais” do Unix, você rapidamente descobrirá que muitas delas não gostam muito do Linux. Eles o consideram impuro e impuro. Um princípio dos usuários Unix é que tudo deve ser “portátil”. Isso significa que qualquer script que você escrever deve ser capaz de rodar, inalterado, em qualquer sistema semelhante ao Unix.
As pessoas do Unix têm boas razões para acreditar nisso. Tendo visto o que as extensões proprietárias para comandos e shells fizeram ao mundo Unix antes do POSIX, eles são naturalmente cautelosos quanto ao efeito do Linux em seu amado SO.
Mas a portabilidade tem uma desvantagem séria. Impede o progresso. Exige que as coisas sempre sejam feitas usando técnicas de “mínimo denominador comum”. No caso da programação shell, significa tornar tudo compatível com sh, o shell Bourne original.
Essa desvantagem é a desculpa que os fornecedores de software proprietário usam para justificar suas extensões proprietárias, mas eles as chamam de “inovações”. Mas eles são, na verdade, apenas dispositivos de bloqueio para seus clientes.
As ferramentas GNU, como bater, não têm tais restrições. Eles encorajam a portabilidade ao apoiar os padrões e ao estarem universalmente disponíveis. Você pode instalar bater e as outras ferramentas GNU em quase qualquer tipo de sistema, até mesmo Windows, sem custo. Portanto, sinta-se à vontade para usar todos os recursos do bater. É clientes portátil.