Наступний код виходить із помилкою незв’язаної змінної. Як це виправити, використовуючи параметр set -oіменника?
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
Відповіді:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
У цьому випадку VALUEзакінчується порожнім рядком, якщо WHATEVERне встановлено. Ми використовуємо {parameter:-word}розширення, яке ви можете знайти в man bashрозділі "Розширення параметрів".
:-перевіряє, чи змінна не встановлена чи порожня. Якщо ви хочете перевірити тільки це знято з охороною, використовуйте -: VALUE=${WHATEVER-}. Крім того, більш читабельний спосіб перевірити, чи порожня змінна:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVERмістить лише пробіли - див. Мою відповідь.
! -z" замість просто " -n"?
Вам потрібно процитувати змінні, якщо ви хочете отримати результат, який очікуєте:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Тест:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
"info bash", "${WHATEVER-}"повинні мати ":"(двокрапка) перед "-"(тире) , як: "${WHATEVER:-}"і "${WHATEVER+defined}"повинні мати двокрапка перед тим , "+"(плюс) , як: "${WHATEVER:+defined}". Для мене це працює в будь-якому випадку, з товстою кишкою або без неї. У деяких версіях 'nix це, ймовірно, не спрацює без включення двокрапки, тому його, мабуть, слід додати.
-, +, :+, і :-все підтримуються. Колишній виявити , чи є змінна встановлена , а останній виявляє він встановлений або порожній . From man bash: "Опускання двокрапки призводить до тесту лише для параметра, який не встановлено."
Як щодо oneliner?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z перевіряє як порожню, так і невстановлену змінну
-zперевіряє лише, якщо наступний параметр порожній. -zє лише аргументом [команди. Змінне розширення відбувається до того, як [ -zможна щось зробити.
Припущення:
$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
Якщо ви хочете, щоб неінтерактивний сценарій надрукував помилку та вийшов, якщо змінна має значення null або не встановлено:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
Якщо ви не хочете, щоб скрипт вийшов:
$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
Ви навіть можете використовувати [і ]замість [[і ]]вище, але останнє є кращим у Bash.
Зверніть увагу на те, що робить товста кишка вище. З документів :
Іншими словами, якщо двокрапка включена, оператор перевіряє наявність обох параметрів і те, що його значення не є нульовим; якщо товста кишка опущена, оператор перевіряє лише наявність.
Очевидно, немає потреби в -nабо -z.
Підсумовуючи, я, як правило, можу просто використовувати [[ "${VAR:?}" ]]. Згідно з прикладами, це друкує помилку і виходить, якщо змінна є нульовою або не встановлена.
Можна використовувати
if [[ ${WHATEVER:+$WHATEVER} ]]; then
але
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
може бути більш читабельним.
=оператор (POSIX) , а не ==для перенесення, а [замість цього, [[якщо це можливо.
set -o nounsetщо характерне для bash. Якщо ви ставите a #!/bin/bashу верхній частині вашого сценарію, то насправді найкраще використовувати вдосконалення bash.
Хоча це не зовсім той випадок використання, про який просили вище, я виявив, що якщо ви хочете використовувати nounset(або-u ) поведінка за замовчуванням - це та, яку ви хочете: вийти з ненульового значення з описовим повідомленням.
Мені знадобилося досить багато часу, щоб усвідомити це, і я зрозумів, що це варто опублікувати як рішення.
Якщо все, що ви хочете - це повторити щось інше під час виходу або провести чистку, ви можете скористатися пасткою.
:-Оператор, ймовірно , що ви хочете , в іншому випадку.