Как определить, пуста ли переменная bash?

Каков наилучший способ определить, является ли переменная в bash пустой ("")?

Я слышал, что мне рекомендуется if [ "x$variable" = "x" ]

Это правильный способ? (должно быть что-то более прямолинейное)

698 голосов | спросил Brent 12 Maypm09 2009, 21:54:48

12 ответов


955

Это вернет true, если переменная не установлена ​​или установлена ​​в пустую строку ("").

if [ -z "$VAR" ];
ответил duffbeer703 12 Maypm09 2009, 22:06:44
220

В Bash, когда вы не занимаетесь переносимостью оболочек, которые его не поддерживают, вы всегда должны использовать синтаксис с двойной скобкой:

Любое из следующего:

if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]

В Bash, используя двойные квадратные скобки, цитаты не нужны. Вы можете упростить тест для переменной, в которой содержит значение:

if [[ $variable ]]

Этот синтаксис совместим с ksh (по крайней мере, ksh93, во всяком случае). Он не работает в чистых POSIX или более старых оболочках Bourne, таких как sh или тире.

См. мой ответ здесь и BashFAQ /031 для получения дополнительной информации о различиях между двойными и одиночными квадратными скобками.

Вы можете проверить, не изменилась ли переменная (в отличие от пустой строки):

if [[ -z ${variable+x} ]]

, где «x» произвольно.

Если вы хотите узнать, является ли переменная нулевой, но не отменяется:

if [[ -z $variable && ${variable+x} ]]
ответил Dennis Williamson 25 FebruaryEurope/MoscowbSat, 25 Feb 2012 07:37:43 +0400000000amSat, 25 Feb 2012 07:37:43 +040012 2012, 07:37:43
202

Переменная в 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}" = "" ], потому что первый аргумент [ ошибочно интерпретируется как оператор -n, а не строка.

ответил Richard Hansen 25 AMpWed, 25 Apr 2012 00:39:38 +040039Wednesday 2012, 00:39:38
35

-z - лучший способ.

Другими параметрами, которые я использовал, является установка переменной, но ее можно переопределить другой переменной, например

export PORT=${MY_PORT:-5432}

Если переменная $MY_PORT пуста, то PORT устанавливается значение 5432, в противном случае для параметра PORT установлено значение MY_PORT. Обратите внимание, что синтаксис включает двоеточие и тире.

ответил Rory 11 J0000006Europe/Moscow 2009, 17:19:09
25

Если вам интересно различать случаи состояния 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
ответил MikeyB 12 Maypm09 2009, 22:21:43
9

Альтернативный вариант, который я видел в [ -z "$foo" ], является следующим, однако я не уверен, почему люди используют этот метод, кто-нибудь знает?

[ "x${foo}" = "x" ]

В любом случае, если вы не разрешаете отменять переменные (либо с помощью set -u, либо set -o nounset), тогда у вас возникнут проблемы с обоими из этих методов , Это простое решение:

[ -z "${foo:-}" ]

Примечание: это оставит вашу переменную undef.

ответил errant.info 20 +04002011-10-20T07:58:35+04:00312011bEurope/MoscowThu, 20 Oct 2011 07:58:35 +0400 2011, 07:58:35
7

вопрос запрашивает , как проверить, является ли переменная пустой строкой , и для нее уже даны лучшие ответы.
Но я приземлился здесь после периода, прошедшего программирование в php, и то, что я на самом деле искал, было проверкой, как функция empty в php , работающая в оболочке bash.
После прочтения ответов я понял, что я не думал правильно в bash, но так или иначе в этот момент функция, подобная empty в php, была бы очень удобной в моем коде bash.
Как я думаю, это может случиться с другими, я решил преобразовать функцию php empty в bash

В соответствии с руководством по php :
переменная считается пустым, если он не существует или его значение является одним из следующих:

  • "" (пустая строка)
  •     
  • 0 (0 как целое число)
  •     
  • 0.0 (0 в качестве поплавка)
  •     
  • "0" (0 в виде строки)
  •     
  • пустой массив
  •     
  • объявленная переменная, но без значения

Конечно, случаи null и false не могут быть преобразованы в 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, любой, кто использует эту функцию, должен оценить этот риск и, возможно, решит сократить эти проверки, оставив только первый.

ответил Luca Borrione 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 01 Sep 2012 00:11:38 +0400 2012, 00:11:38
6

все if-then и -z не нужны.

["$ foo"] & & & echo "foo не пуст"
["$ foo"] || echo "foo действительно пуст"
ответил 26 Jpm1000000pmTue, 26 Jan 2010 17:02:09 +030010 2010, 17:02:09
5

Это верно, когда $ FOO установлен и пуст:

[ "${FOO+x}" = x ] && [ -z "$FOO" ]
ответил 21 Mayam10 2010, 00:52:31
5

Лично предпочитайте более четкий способ проверки:

if [ "${VARIABLE}" == "" ]; then
  echo VARIABLE is empty
else
  echo VARIABLE is not empty
fi
ответил Fedir RYKHTIK 9 FriEurope/Moscow2011-12-09T19:15:29+04:00Europe/Moscow12bEurope/MoscowFri, 09 Dec 2011 19:15:29 +0400 2011, 19:15:29
4

Мои 5 центов: есть более короткий синтаксис, чем if ..., этот:

VALUE="${1?"Usage: $0 value"}"

В этой строке будет установлено значение VALUE, если аргумент предоставлен, и выведет сообщение об ошибке, добавленное с номером строки сценария, в случае ошибки (и завершит выполнение скрипта).

Другой пример можно найти в abs-guide (найдите «Пример 10-7»).

ответил gluk47 9 12015vEurope/Moscow11bEurope/MoscowMon, 09 Nov 2015 19:46:15 +0300 2015, 19:46:15
3

расширение oneliner решение duffbeer703 :

#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
ответил andrej 31 PM00000030000002131 2012, 15:34:21

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132