Якщо ваш $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)