Editar: esta é uma versão mais completa que mostra mais diferenças entre [
(aka test
) e [[
.
A tabela a seguir mostra que, se uma variável é citada ou não, se você usa colchetes simples ou duplos e se a variável contém apenas um espaço, isso afeta o fato de o uso de um teste com ou sem -n/-z
ser adequado para verificar uma variável.
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
Se você deseja saber se uma variável tem comprimento diferente de zero, siga um destes procedimentos:
- cite a variável entre colchetes (coluna 2a)
- use
-n
e cite a variável entre colchetes (coluna 4a)
- use colchetes duplos com ou sem aspas e com ou sem
-n
(colunas 1b - 4b)
Observe na coluna 1a, começando na linha rotulada "dois", que o resultado indica que [
está avaliando o conteúdo da variável como se eles fizessem parte da expressão condicional (o resultado corresponde à afirmação implícita no "T" ou "F" em a coluna de descrição). Quando [[
é usado (coluna 1b), o conteúdo da variável é visto como uma sequência e não é avaliado.
Os erros nas colunas 3a e 5a são causados pelo fato de o valor da variável incluir um espaço e a variável não estar entre aspas. Novamente, como mostrado nas colunas 3b e 5b, [[
avalia o conteúdo da variável como uma sequência.
Da mesma forma, para testes para cadeias de comprimento zero, as colunas 6a, 5b e 6b mostram as maneiras corretas de fazer isso. Observe também que qualquer um desses testes pode ser negado se negar mostrar uma intenção mais clara do que usar a operação oposta. Por exemplo: if ! [[ -n $var ]]
.
Se você estiver usando [
, a chave para garantir que você não obtenha resultados inesperados é citar a variável. Usando [[
, isso não importa.
As mensagens de erro que estão sendo suprimidas são "operador unário esperado" ou "operador binário esperado".
Este é o script que produziu a tabela acima.
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF
["
vs[-n"
(a primeira pergunta do OP) mostra que eles são completamente equivalentes, certo?[["
É melhor usar o mais poderoso no
[[
que diz respeito ao Bash.Casos usuais
As duas construções acima parecem limpas e legíveis. Eles devem bastar na maioria dos casos.
Observe que não precisamos citar as expansões variáveis internas,
[[
pois não há perigo de divisão e globbing de palavras .Para evitar queixas macias do shellcheck sobre
[[ $var ]]
e[[ ! $var ]]
, poderíamos usar a-n
opçãoCasos raros
No raro caso de termos que fazer uma distinção entre "ser definido como uma cadeia vazia" vs "não ser definido", poderíamos usá-los:
Também podemos usar o
-v
teste:Publicações e documentação relacionadas
Há muitas postagens relacionadas a esse tópico. Aqui estão alguns:
[[
vs[
[
vs[[
fonte
Aqui estão mais alguns testes
Verdadeiro se a sequência não estiver vazia:
Verdadeiro se a sequência estiver vazia:
fonte
A resposta correta é a seguinte:
Observe o uso de
[[...]]
, que manipula corretamente citando as variáveis para você.fonte
-n
quando não é realmente necessário no Bash?Uma maneira alternativa e talvez mais transparente de avaliar uma variável de ambiente vazia é usar ...
fonte
bash
é uma ferramenta mais nítida que seus antecessores.[ "$ENV_VARIABLE" != "" ]
funcionará em todos os shell com umatest
implementação compatível com POSIX - não apenas o bash, mas o ash / dash / ksh / etc.-a
ou-o
combine testes, mas use[ ... ] && [ ... ]
or[ ... ] || [ ... ]
e os únicos casos de canto que podem ser aplicados ao uso de dados de variáveis arbitrárias em um teste são fechados sem ambiguidade.Use
case/esac
para testar:fonte
case
serve.case
funciona melhor quando há mais de duas alternativas.case
não se destina a esse tipo de uso.