Я не смог найти ни одного простого и понятного ресурса с описанием значения и исправлением следующей ошибки оболочки BASH, поэтому я публикую то, что нашел после исследования.
Ошибка:
-bash: [: too many arguments
Google-Версия: bash open square bracket colon too many arguments
.
Контекст: условие if в квадратных скобках с простым оператором сравнения, например, равно, больше чем, например, например:
VARIABLE=$(/some/command);
if [ $VARIABLE == 0 ]; then
# some action
fi
bash
if-statement
arguments
user56reinstatemonica8
источник
источник
Ответы:
Если ваша
$VARIABLE
строка содержит пробелы или другие специальные символы и используются одинарные квадратные скобки (что является сокращением дляtest
команды), то строка может быть разбита на несколько слов. Каждый из них рассматривается как отдельный аргумент.Так что одна переменная разбивается на множество аргументов :
То же самое будет верно для любого вызова функции, который записывает строку, содержащую пробелы или другие специальные символы.
Легко исправить
Оберните вывод переменной в двойные кавычки, заставив его остаться как одна строка (следовательно, один аргумент). Например,
Просто как тот. Но перейдите к пункту «Также будьте осторожны ...» ниже, если вы также не можете гарантировать, что ваша переменная не будет пустой строкой или строкой, которая содержит только пробелы.
Или альтернативным решением является использование двойных квадратных скобок (что является сокращением для
new test
команды).Это существует только в bash (и, по-видимому, korn и zsh), и поэтому может быть несовместимо с оболочками по умолчанию, вызываемыми и
/bin/sh
т. Д.Это означает, что в некоторых системах он может работать с консоли, но не при вызове в другом месте, например
cron
, в зависимости от того, как все настроено.Это будет выглядеть так:
Если ваша команда содержит двойные квадратные скобки, подобные этой, и вы получаете ошибки в журналах, но она работает из консоли, попробуйте заменить
[[
альтернативу, предложенную здесь, или убедитесь, что во всех ваших скриптах используется оболочка, которая поддерживает[[
akanew test
.Также остерегайтесь
[: unary operator expected
ошибокЕсли вы видите ошибку «слишком много аргументов», скорее всего, вы получаете строку из функции с непредсказуемым выводом. Если также возможно получить пустую строку (или всю строку пробела), это будет рассматриваться как нулевые аргументы даже с указанным выше «быстрым исправлением» и завершится ошибкой с
[: unary operator expected
Это то же самое «гоча», если вы привыкли к другим языкам - вы не ожидаете, что содержимое переменной будет эффективно напечатано в коде, подобном этому, до его оценки.
Вот пример, который предотвращает как ошибки, так
[: too many arguments
и[: unary operator expected
ошибки: замена вывода значением по умолчанию, если оно пустое (в этом примере,0
), с двойными кавычками, обернутыми вокруг всего:(здесь действие произойдет, если $ VARIABLE равно 0 или пусто. Естественно, вы должны изменить 0 (значение по умолчанию) на другое значение по умолчанию, если требуется другое поведение)
Последнее замечание: поскольку
[
это сокращениеtest
, все вышесказанное также верно для ошибкиtest: too many arguments
(и такжеtest: unary operator expected
)источник
i=$(some_command); i=$((i)); if [ "$i" == 0 ] ...
Просто наткнулся на этот пост, получая ту же ошибку, пытаясь проверить, являются ли две переменные обе пустыми (или непустыми). Это оказывается сложным сравнением - 7.3. Другие операторы сравнения - Расширенное руководство по написанию сценариев ; и я подумал, что должен отметить следующее:
Сначала я думал, что это означает «пустой»; но это означает, что «файл существует» - используйте-e
-z
для проверки пустой переменной (строки)test
с и&&
их:[ ... ] && [ ... ]
-a
оператор в одномtest
:[ ... -a ... ]
Вот рабочая команда (поиск по всем txt-файлам в каталоге и выгрузка
grep
найденных файлов, содержащих оба слова):Изменить 12 августа 2013: примечание к соответствующей проблеме:
Обратите внимание, что при проверке равенства строк с помощью классического
test
(одна квадратная скобка[
), вы ДОЛЖНЫ иметь пробел между оператором «равно», который в этом случае является единственным=
знаком «равно» (хотя два знака==
равенства кажутся принятыми как равенство оператор тоже). Таким образом, это терпит неудачу (молча):... но добавьте пробел - и все выглядит хорошо:
источник
((A || B) && C)
?Другой сценарий, который вы можете получить,
[: too many arguments
или[: a: binary operator expected
ошибки, если вы пытаетесь проверить все аргументы"$@"
Это работает правильно, если вы звоните
foo.sh
илиfoo.sh arg1
. Но если вы передадите несколько аргументов, какfoo.sh arg1 arg2
, вы получите ошибки. Это потому, что он расширяется до[ -z arg1 arg2 ]
, что не является допустимым синтаксисом.Правильный способ проверить наличие аргументов есть
[ "$#" -eq 0 ]
. ($#
количество аргументов).источник
Несколько раз, если вы случайно коснулись клавиатуры и убрали пробел.
Вызовет это сообщение об ошибке. Обратите внимание на пробел перед ']'.
источник
У меня была такая же проблема с моими сценариями. Но когда я сделал некоторые изменения, это сработало для меня. Я сделал это так:
таким образом я решил свою проблему. Надеюсь, что это поможет и вам.
источник