Якщо ваш $VARIABLE
рядок містить пробіли або інші спеціальні символи, і використовуються одинарні квадратні дужки (що є ярликом для test
команди), то рядок може бути розбита на кілька слів. Кожне з них трактується як окремий аргумент.
Так що одна змінна розділена на багато аргументів :
VARIABLE=$(/some/command);
# returns "hello world"
if [ $VARIABLE == 0 ]; then
# fails as if you wrote:
# if [ hello world == 0 ]
fi
Те саме буде справедливо для будь-якого виклику функції, який висуває рядок, що містить пробіли або інші спеціальні символи.
Легке виправлення
Оберніть змінний вихід у подвійні лапки, змусивши його залишатися як один рядок (отже, один аргумент). Наприклад,
VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
# some action
fi
Просто як це. Але перейдіть до пункту "Також будьте обережні ...", якщо ви також не можете гарантувати, що ваша змінна не буде порожньою рядком або рядком, що не містить нічого, крім пробілу.
Або альтернативним виправленням є використання подвійних квадратних дужок (що є ярликом для new test
команди).
Однак це існує лише в bash (і, мабуть, korn і zsh), і тому може бути не сумісно з оболонками за замовчуванням, викликаними і /bin/sh
т.д.
Це означає, що в деяких системах воно може працювати з консолі, але не тоді, коли викликається в іншому місці, як-отcron
, залежно від того, як все налаштовано.
Це виглядатиме так:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
Якщо ваша команда містить подвійні квадратні дужки на кшталт цього, і ви отримуєте помилки в журналах, але це працює з консолі, спробуйте замінити на [[
запропоновану тут альтернативу або переконайтеся, що все, що виконує ваш сценарій, використовує оболонку, яка підтримує [[
ака new test
.
Також остерігайтесь [: unary operator expected
помилки
Якщо ви бачите помилку "занадто багато аргументів", швидше за все, ви отримаєте рядок з функції з непередбачуваним результатом. Якщо також можливо отримати порожній рядок (або всю рядок пробілів), це трактуватиметься як нульовий аргумент навіть із вищевказаним "швидким виправленням", і не вдасться з[: unary operator expected
Це те саме "gotcha", якщо ви звикли до інших мов - ви не очікуєте, що вміст змінної буде ефективно надруковано в код, як цей, перш ніж він буде оцінений.
Ось приклад, який запобігає [: too many arguments
і [: unary operator expected
помилки, і помилки: заміна виводу значенням за замовчуванням, якщо він порожній (у цьому прикладі 0
), подвійними лапками, обернутими навколо всього:
VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
# some action
fi
(тут дія відбудеться, якщо $ VARIABLE дорівнює 0, або порожній. Природно, ви повинні змінити 0 (значення за замовчуванням) на інше значення за замовчуванням, якщо потрібна інша поведінка)
Остаточне зауваження: оскільки [
це ярлик для test
, все вищезазначене також стосується помилки test: too many arguments
(а також test: unary operator expected
)