Стару версію відповіді див. У другій частині цієї відповіді. Якщо ви хочете дізнатися про деталі, читайте далі
Причина випуску
У самому питанні повідомляється, що ОП бачить too many arguments error, що при тестуванні bashне здається:
$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected
З /bin/shякою фактично посилається /bin/dashна Ubuntu, про помилку повідомляється наступним чином:
$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator
І окремий /bin/testтакож:
$ /usr/bin/test $1 != ''
/usr/bin/test: missing argument after ‘’
Sidenote: Якщо вам цікаво , що /usr/bin/testі чому я використовую bashі sh, то ви повинні знати , що [це псевдонім для testкоманди, яка також існує як окремий виконуваний файл або частіше - в якості оболонки вбудованої в якій то , що кожна оболонка буде використовувати перший . Що стосується ifвисловлювань, вони працюють на статусах виходу команд, отже, чому [і testє командами, причому все інше є аргументами для цих команд - неправильний порядок цих аргументів командного рядка призводить до помилок.
Повернутися до теми: незрозуміло, як ОП отримала непов’язану помилку. Однак у всіх 3 випадках проблема однакова - незмінна змінна буде розглядатися як порожня, тому те, що оболонка бачить із цими цитованими змінними, є
[ != '' ]
який розбиває синтаксис, який testрозуміє. Пам'ятаєте, що я сказав про неправильний порядок аргументів командного рядка? Отже, чому цитування важливе. Увімкніть діагностичний вихід і подивимося, що виконується оболонка:
$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ]
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars
Кращий спосіб перевірити невстановлені змінні
Дуже частий підхід, який ви бачите навколо:
if [ "x$var1" == "x" ] && [ "x$var2" == "x" ];
then
echo "both variables are null"
fi
Щоб цитувати Жиля :
У ["x $ 1" = "x"] префікс x гарантує, що x "$ 1" не може бути схожим на оператора, тому єдиним способом оболонка може проаналізувати цей тест, трактуючи = як двійковий оператор.
Імовірно, це має бути досить портативно, оскільки я бачив це у /bin/shсценаріях. Він також може поєднуватися як в
if [ "x${var1}${var2}" == "x" ]; then
...
fi
Звичайно, ми можемо використовувати -zпрапор, однак згідно з дослідженнями в деяких снарядах, зокрема ksh88 (за словами Стефана Шазеласа ), цей прапор є несправним.
Дивитися також