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