Редактировать: это более полная версия, которая показывает больше различий между [
(ака test
) и [[
.
В следующей таблице показано, что независимо от того, указана ли переменная в кавычках или нет, используете ли вы одинарные или двойные скобки и содержит ли переменная только пробел, это то, что влияет на то, подходит ли использование теста с или без -n/-z
проверки для проверки переменной.
| 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
Если вы хотите узнать, имеет ли переменная ненулевую длину, выполните одно из следующих действий:
- заключите переменную в квадратные скобки (столбец 2a)
- используйте
-n
и заключите в кавычки переменную (столбец 4a)
- используйте двойные скобки с или без кавычек и с или без
-n
(столбцы 1b - 4b)
Обратите внимание, что в столбце 1a, начинающемся со строки, помеченной как «два», результат указывает, что [
оценивает содержимое переменной, как если бы она была частью условного выражения (результат соответствует утверждению, подразумеваемому «T» или «F» в столбец описания). Когда [[
используется (столбец 1b), содержимое переменной рассматривается как строка и не оценивается.
Ошибки в столбцах 3a и 5a вызваны тем, что значение переменной содержит пробел, а переменная не заключена в кавычки. Опять же, как показано в столбцах 3b и 5b, [[
оценивает содержимое переменной как строку.
Соответственно, для тестов для строк нулевой длины столбцы 6a, 5b и 6b показывают правильные способы сделать это. Также обратите внимание, что любой из этих тестов может быть отменен, если отрицание показывает более ясное намерение, чем использование противоположной операции. Например: if ! [[ -n $var ]]
.
Если вы используете [
, ключом к тому, чтобы убедиться, что вы не получите неожиданных результатов, является цитирование переменной. Использование [[
, это не имеет значения.
Сообщения об ошибках, которые подавляются, представляют собой «ожидается унарный оператор» или «ожидается двоичный оператор».
Это скрипт, который создал таблицу выше.
#!/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
["
против[-n"
(первый вопрос ОП) показывает, что они полностью эквивалентны, верно?[["
Лучше использовать более мощный,
[[
что касается Bash.Обычные случаи
Вышеуказанные две конструкции выглядят чистыми и читаемыми. Их должно хватить в большинстве случаев.
Обратите внимание , что мы не должны процитировать переменных разложение внутри ,
[[
поскольку нет никакой опасности слова расщепления и универсализации .Чтобы предотвратить мягкие жалобы Shellcheck по поводу
[[ $var ]]
и[[ ! $var ]]
, мы могли бы использовать эту-n
опцию.Редкие случаи
В редких случаях, когда нам нужно было различать «быть установленным на пустую строку» и «не быть установленным вообще», мы могли бы использовать это:
Мы также можем использовать
-v
тест:Связанные посты и документация
Есть много сообщений, связанных с этой темой. Вот несколько из них:
[[
против[
[
против[[
источник
Вот еще несколько тестов
Истинно, если строка не пуста:
Истинно, если строка пуста:
источник
Правильный ответ следующий:
Обратите внимание на использование
[[...]]
, которое правильно обрабатывает кавычки переменных для вас.источник
-n
когда это не очень нужно в Bash?Альтернативный и, возможно, более прозрачный способ оценки пустой переменной среды - использовать ...
источник
bash
является более острым инструментом, чем его предшественники.[ "$ENV_VARIABLE" != "" ]
будет работать на каждой оболочке с POSIX-совместимойtest
реализацией - не только bash, но и ash / dash / ksh / etc.-a
или-o
комбинировать тесты, но вместо этого использовать[ ... ] && [ ... ]
или[ ... ] || [ ... ]
и единственные угловые случаи, которые могут применяться к использованию данных произвольных переменных в тесте, однозначно закрыты.Используйте
case/esac
для проверки:источник
case
предназначено для.case
лучше всего работает, когда есть более двух альтернатив.case
не предназначен для этого вида использования.