Для старой версии ответа см. Вторую часть этого ответа. Если вы хотите узнать о деталях, читайте дальше
Причина проблемы
В самом вопросе сообщается, что OP видит 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являются командами, а все остальное является аргументами этих команд - неправильный порядок этих аргументов командной строки приводит к ошибкам.
Вернемся к теме: неясно, как ОП получил несвязанную ошибку. Однако во всех трех случаях проблема одна и та же - неустановленная переменная будет считаться пустой, поэтому оболочка с этими переменными без кавычек выглядит так:
[ != '' ]
который нарушает синтаксис, который 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 (согласно Стефану Чазеласу ), этот флаг неисправен.
Смотрите также