Ответы:
Это вернет true, если переменная не установлена или установлена в пустую строку ("").
if [ -z "$VAR" ];
if [ ! -z "$VAR" ];
-z
это-n
if [ -n "$VAR" ];
$var
в командной строке будет разбито пробелом на список параметров, в то время как "$var"
всегда будет только один параметр. Заключение в кавычки переменных часто является хорошей практикой и не дает вам запутаться в именах файлов, содержащих пробелы (среди прочего). Пример: после этого a="x --help"
попробуйте cat $a
- он откроет вам страницу помощи для cat
. Тогда попробуй cat "$a"
- он (обычно) скажет cat: x --help: No such file or directory
. Короче, цитируйте рано и часто цитируйте, и вы почти никогда не пожалеете об этом.
В Bash, когда вас не интересует переносимость в оболочки, которые ее не поддерживают, вы всегда должны использовать синтаксис в двойных скобках:
Любое из следующего:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
В Bash, используя двойные квадратные скобки, кавычки не нужны. Вы можете упростить тест для переменной, которая содержит значение для:
if [[ $variable ]]
Этот синтаксис совместим с ksh (по крайней мере, ksh93, в любом случае). Он не работает в чистых оболочках POSIX или старых Bourne, таких как sh или dash.
Смотрите мой ответ здесь и BashFAQ / 031 для получения дополнительной информации о различиях между двойными и одинарными квадратными скобками.
Вы можете проверить, является ли переменная не установленной (в отличие от пустой строки):
if [[ -z ${variable+x} ]]
где «х» является произвольным.
Если вы хотите узнать, является ли переменная нулевой, но не не установлена ли она:
if [[ -z $variable && ${variable+x} ]]
if [[ $variable ]]
работало хорошо для меня, и даже не нуждалось в том, set -u
что требовалось одним из других предложенных решений.
sh
вместо Bash. Если вам нужны расширенные возможности, которые он предоставляет, используйте Bash и используйте его полностью.
;
в конце. then
Может быть на следующей строке без запятой вообще.
Переменная в bash (и любая POSIX-совместимая оболочка) может находиться в одном из трех состояний:
В большинстве случаев вам нужно только знать, установлена ли переменная в непустую строку, но иногда важно различать unset и задавать пустую строку.
Ниже приведены примеры того, как вы можете протестировать различные возможности, и это работает в bash или любой POSIX-совместимой оболочке:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR is either unset or set to a non-empty string"
fi
Вот то же самое, но в удобной форме таблицы:
+-------+-------+-----------+
VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | true | true | false |
| [ -z "${VAR+set}" ] | true | false | false |
| [ -z "${VAR-unset}" ] | false | true | false |
| [ -n "${VAR}" ] | false | false | true |
| [ -n "${VAR+set}" ] | false | true | true |
| [ -n "${VAR-unset}" ] | true | false | true |
+-----------------------+-------+-------+-----------+
${VAR+foo}
Конструкция раскрывается в пустую строку , если VAR
она не задана , или foo
если VAR
установлено что - то ( в том числе пустая строка).
${VAR-foo}
Конструкция расширяется до значения , VAR
если установлено ( в том числе установить в пустую строку) и foo
если не задано. Это полезно для обеспечения переопределяемых пользователем значений по умолчанию (например, ${COLOR-red}
говорит , что использовать, red
если переменная COLOR
не была установлена на что-то).
Причина, по которой [ x"${VAR}" = x ]
часто рекомендуется проверять, является ли переменная неустановленной или установлена в пустую строку, заключается в том, что некоторые реализации [
команды (также известные как test
) содержат ошибки. Если VAR
установлено что-то вроде -n
, то некоторые реализации будут делать неправильно, когда дано, [ "${VAR}" = "" ]
потому что первый аргумент to [
ошибочно интерпретируется как -n
оператор, а не строка.
[ -z "${VAR-set}" ]
.
set -u
или set -o nounset
в bash, то проверка просто выдаст ошибку «bash: VAR: unbound variable». См. Stackoverflow.com/a/13864829 для более надежной проверки сброса. Моя проверка, является ли переменная нулевой или неустановленной [ -z "${VAR:-}" ]
. Моя проверка , является ли переменная непустое это [ "${VAR:-}" ]
.
-z
это лучший способ.
Другие опции, которые я использовал, это установить переменную, но она может быть переопределена другой переменной, например
export PORT=${MY_PORT:-5432}
Если $MY_PORT
переменная пуста, то PORT
устанавливается значение 5432, в противном случае значение PORT устанавливается равным значению MY_PORT
. Обратите внимание, синтаксис включает двоеточие и тире.
set -o nounset
в некоторых сценариях.
Альтернативой, которую я видел, [ -z "$foo" ]
является следующее, однако я не уверен, почему люди используют этот метод, кто-нибудь знает?
[ "x${foo}" = "x" ]
В любом случае, если вы не разрешите неустановленные переменные (либо с помощью, set -u
либо set -o nounset
), то у вас возникнут проблемы с обоими этими методами. Это простое решение:
[ -z "${foo:-}" ]
Примечание: это оставит вашу переменную undef.
-z
на pubs.opengroup.org/onlinepubs/009695399/utilities/test.html . По сути, это не означает, что является альтернативой -z
. Скорее, он обрабатывает случаи, когда $foo
может расшириться до чего-то, начинающегося с метасимвола, который [
или test
будет смущен. Помещение произвольного неметасимвола в начале исключает эту возможность.
Вопрос спрашивает , как проверить , является ли переменная пустая строка и лучшие ответы уже даны для этого.
Но я попал сюда после того, как прошел период программирования на php, и то, что я действительно искал, было проверкой, похожей на пустую функцию в php, работающую в оболочке bash.
Прочитав ответы, я понял, что не думаю о bash должным образом, но в любом случае в моем bash-коде такая функция, как empty в php, была бы очень удобной.
Поскольку я думаю, что это может случиться с другими, я решил преобразовать пустую функцию php в bash
Согласно руководству по php :
переменная считается пустой, если она не существует или если ее значение является одним из следующих:
Конечно, нулевые и ложные случаи не могут быть преобразованы в bash, поэтому они опущены.
function empty
{
local var="$1"
# Return true if:
# 1. var is a null string ("" as empty string)
# 2. a non set variable is passed
# 3. a declared variable or array but without a value is passed
# 4. an empty array is passed
if test -z "$var"
then
[[ $( echo "1" ) ]]
return
# Return true if var is zero (0 as an integer or "0" as a string)
elif [ "$var" == 0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
# Return true if var is 0.0 (0 as a float)
elif [ "$var" == 0.0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
fi
[[ $( echo "" ) ]]
}
Пример использования:
if empty "${var}"
then
echo "empty"
else
echo "not empty"
fi
Демо:
следующий фрагмент:
#!/bin/bash
vars=(
""
0
0.0
"0"
1
"string"
" "
)
for (( i=0; i<${#vars[@]}; i++ ))
do
var="${vars[$i]}"
if empty "${var}"
then
what="empty"
else
what="not empty"
fi
echo "VAR \"$var\" is $what"
done
exit
выходы:
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
Сказав, что в логике bash проверки на ноль в этой функции могут вызвать побочные проблемы imho, любой, кто использует эту функцию, должен оценить этот риск и, возможно, решит отключить эти проверки, оставив только первую.
empty
- почему вы пишете, [[ $( echo "1" ) ]] ; return
а не просто return 1
?
все if-then и -z не нужны.
["$ foo"] && echo "foo не пустой" ["$ foo"] || echo "foo действительно пусто"
Это верно именно тогда, когда $ FOO установлен и пуст:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Лично предпочитаю более понятный способ проверки:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
Расширение oneliner решения duffbeer703 :
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
Мои 5 центов: есть также более короткий синтаксис, чем if ...
этот:
VALUE="${1?"Usage: $0 value"}"
Эта строка установит VALUE, если был предоставлен аргумент, и напечатает сообщение об ошибке с добавлением номера строки сценария в случае ошибки (и прекратит выполнение сценария).
Другой пример можно найти в руководстве по abs (поиск «Пример 10-7»).
Не точный ответ, но наткнулся на этот трюк. Если искомая строка взята из «команды», вы можете сохранить команду в env. переменной, а затем выполняйте ее каждый раз для оператора if, тогда скобки не требуются!
Например, эта команда, которая определяет, используете ли вы Debian:
grep debian /proc/version
полный пример:
IS_DEBIAN="grep -i debian /proc/version"
if $IS_DEBIAN; then
echo 'yes debian'
else
echo 'non debian'
fi
Так что это похоже на косвенный способ (повторный запуск каждый раз), чтобы проверить пустую строку (это происходит проверка ответа на ошибку от команды, но это также происходит, чтобы вернуть пустую строку).