Подтвердить что ты не робот

Использование unset против установки переменной в пустую

В настоящее время я пишу структуру тестирования bash, где в тестовой функции могут использоваться как стандартные тесты bash ([[), так и предопределенные сопоставления. Матчи являются оболочками для "[['и, кроме того, возвращают код возврата, устанавливают какое-то содержательное сообщение о том, что ожидалось.

Пример:

string_equals() {
    if [[ ! $1 = $2 ]]; then
            error_message="Expected '$1' to be '$2'."

            return 1
    fi
}

Итак, когда используется соединитель, и он терпит неудачу, только тогда устанавливается значение error_message.

Теперь, в какой-то момент, я проверю, прошли ли тесты. Если это удалось, я печатаю ожидание зеленым цветом, если оно не красное.

Кроме того, может быть установлен параметр error_message, поэтому я проверяю, существует ли сообщение, печатайте его и затем отключите (поскольку следующий тест не может установить error_message):

if [[ $error_message ]]; then
    printf '%s\n' "$error_message"

    unset -v error_message
fi

Теперь мой вопрос: если лучше отключить переменную или просто установить ее в '', например

error_message=''

Какой из них лучше? Действительно ли это имеет значение? Или, может быть, должен ли я иметь дополнительный флаг, указывающий, что сообщение было установлено?

4b9b3361

Ответ 1

В основном вы не видите разницы, если вы не используете set -u:

/home/user1> var=""
/home/user1> echo $var

/home/user1> set -u
/home/user1> echo $var

/home/user1> unset var
/home/user1> echo $var
-bash: var: unbound variable

Итак, это зависит от того, как вы собираетесь тестировать переменную.

Я добавлю, что мой предпочтительный способ тестирования, если он установлен:

[[ -n $var ]]  # True if not zero length

или

[[ -z $var ]]  # True if zero length

Ответ 2

Как было сказано, использование unset также отличается от массивов

$ foo=(4 5 6)

$ foo[2]=

$ echo ${#foo[*]}
3

$ unset foo[2]

$ echo ${#foo[*]}
2