Как лучше всего определить, является ли переменная в bash пустой ("")?
Я слышал, что мне рекомендуется if [ "x$variable" = "x" ]
Это верный путь? (должно быть что-то более простое)
Это вернет истину, если переменная не установлена или установлена на пустую строку ("").
if [ -z "${VAR}" ];
В 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} ]]
Переменная в bash (и любой POSIX-совместимой оболочке) может находиться в одном из трех состояний:
В большинстве случаев вам нужно только знать, установлена ли переменная в непустую строку, но иногда важно различать неустановленную и установленную на пустую строку.
Ниже приведены примеры того, как вы можете протестировать различные возможности, и это работает в 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}" = "" ]
потому что первый аргумент [
ошибочно интерпретируется как -n
оператор, а не строка.
-z
это лучший способ.
Еще один вариант, который я использовал, - установить переменную, но ее можно переопределить другой переменной, например
export PORT=${MY_PORT:-5432}
Если $MY_PORT
переменная пуста, тогда PORT
получает значение 5432, в противном случае для ПОРТ устанавливается значение MY_PORT
. Обратите внимание, что синтаксис включает двоеточие и тире.
Если вас интересует различие между состояниями set-empty и unset, посмотрите на параметр -u для bash:
$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR
$ [ -z "$BAR" ] && echo true
true
Альтернатива, которую я видел [ -z "$foo" ]
следующее, однако я не уверен, почему люди используют этот метод, кто-нибудь знает?
[ "x${foo}" = "x" ]
В любом случае, если вы запрещаете неустановленные переменные (либо set -u
или set -o nounset
), то у вас возникнут проблемы с обоими этими методами. Для этого есть простое решение:
[ -z "${foo:-}" ]
Примечание: это оставит вашу переменную undef.
В вопрос спрашивает как проверить, является ли переменная пустой строкой и на это уже даны лучшие ответы.
Но я приземлился здесь после того, как прошел период программирования на php, и на самом деле я искал проверку вроде пустая функция в php работает в оболочке bash.
Прочитав ответы, я понял, что неправильно думаю в bash, но, тем не менее, в тот момент функция вроде пустой в php было бы так удобно в моем коде на bash.
Поскольку я думаю, что это может случиться с другими, я решил преобразовать пустую функцию 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, любой, кто использует эту функцию, должен оценить этот риск и, возможно, решить отключить эти проверки, оставив только первый.
все if-then и -z не нужны.
[ "$foo" ] && echo "foo is not empty" [ "$foo" ] || echo "foo is indeed empty"
Мои 5 центов: также есть более короткий синтаксис, чем if ...
, вот этот:
VALUE="${1?"Usage: $0 value"}"
В этой строке будет установлено ЗНАЧЕНИЕ, если был предоставлен аргумент, и будет напечатано сообщение об ошибке с добавлением номера строки сценария в случае ошибки (и завершится выполнение сценария).
Другой пример можно найти в абс-гид (ищите «Пример 10-7»).
Это верно, когда $ FOO установлен и пуст:
[ "${FOO+x}" = x ] && [ -z "$FOO" ]
Лично предпочитаю более понятный способ проверки:
if [ "${VARIABLE}" == "" ]; then
echo VARIABLE is empty
else
echo VARIABLE is not empty
fi
одноразовое расширение duffbeer703решение:
#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
Не точный ответ, но наткнулся на эту уловку. Если строка, которую вы ищете, происходит от «команды», вы можете сохранить команду в 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
Таким образом, это похоже на косвенный способ (повторный запуск его каждый раз) для проверки пустой строки (это проверяет ответ на ошибку от команды, но он также возвращает пустую строку).