Nie mogłem znaleźć żadnego prostego, prostego zasobu, który wyjaśnia znaczenie i naprawę następującego błędu powłoki BASH, więc publikuję to, co znalazłem po zbadaniu.
Błąd:
-bash: [: too many arguments
Google Wersja: bash open square bracket colon too many arguments
.
Kontekst: warunek if w pojedynczych nawiasach kwadratowych z prostym operatorem porównania, takim jak równy, większy niż itp., Na przykład:
VARIABLE=$(/some/command);
if [ $VARIABLE == 0 ]; then
# some action
fi
bash
if-statement
arguments
user56reinstatemonica8
źródło
źródło
Odpowiedzi:
Jeśli twój
$VARIABLE
jest ciągiem zawierającym spacje lub inne znaki specjalne, a używane są pojedyncze nawiasy kwadratowe (co jest skrótem dotest
polecenia), to ciąg może być podzielony na wiele słów. Każdy z nich jest traktowany jako osobny argument.Tak więc jedna zmienna jest podzielona na wiele argumentów :
To samo dotyczy każdego wywołania funkcji, które odkłada ciąg znaków zawierający spacje lub inne znaki specjalne.
Łatwa naprawa
Zawiń dane wyjściowe zmiennej w podwójne cudzysłowy, zmuszając ją do pozostania jako jeden ciąg (a zatem jeden argument). Na przykład,
Proste. Przejdź jednak do „Uważaj też ...” poniżej, jeśli nie możesz zagwarantować, że zmienna nie będzie ciągiem pustym lub ciągiem znaków, który nie zawiera nic oprócz białych znaków.
Lub alternatywną poprawką jest użycie podwójnych nawiasów kwadratowych (co jest skrótem dla
new test
polecenia).Istnieje to jednak tylko w bash (i najwyraźniej korn i zsh), więc może nie być kompatybilny z domyślnymi powłokami wywoływanymi przez
/bin/sh
itp.Oznacza to, że w niektórych systemach może działać z konsoli, ale nie jest wywoływany gdzie indziej, na przykład z
cron
, w zależności od konfiguracji wszystkiego.Wyglądałoby to tak:
Jeśli twoje polecenie zawiera podwójne nawiasy kwadratowe i wyświetlasz błędy w logach, ale działa ono z konsoli, spróbuj zamienić
[[
alternatywę na sugerowaną tutaj alternatywę lub upewnij się, że cokolwiek uruchamia skrypt używa powłoki obsługującej[[
akanew test
.Uważaj również na
[: unary operator expected
błądJeśli widzisz błąd „zbyt wielu argumentów”, możliwe, że otrzymujesz ciąg znaków z funkcji o nieprzewidywalnym wyniku. Jeśli możliwe jest również uzyskanie pustego łańcucha (lub całego łańcucha spacji), byłoby to traktowane jako zero argumentów, nawet przy powyższej „szybkiej poprawce”, i nie powiodło się
[: unary operator expected
To samo „gotcha”, jeśli jesteś przyzwyczajony do innych języków - nie spodziewasz się, że zawartość zmiennej zostanie skutecznie wydrukowana w takim kodzie, zanim zostanie sprawdzona.
Oto przykład, który zapobiega zarówno błędom, jak
[: too many arguments
i[: unary operator expected
błędom: zastąpienie wyjścia wartością domyślną, jeśli jest puste (w tym przykładzie,0
), z podwójnymi cudzysłowami owiniętymi wokół całej rzeczy:(tutaj akcja nastąpi, jeśli $ VARIABLE ma wartość 0 lub jest pusta. Naturalnie, powinieneś zmienić 0 (wartość domyślna) na inną wartość domyślną, jeśli pożądane jest inne zachowanie)
Uwaga końcowa: Ponieważ
[
jest to skróttest
, wszystkie powyższe dotyczy również błędutest: too many arguments
(i równieżtest: unary operator expected
)źródło
i=$(some_command); i=$((i)); if [ "$i" == 0 ] ...
Po prostu wpadł na to stanowisko, uzyskując ten sam błąd, próbując testu, jeśli dwie zmienne są zarówno pusta (lub nie jest pusty). To okazuje się być złożonym porównaniem - 7.3. Inne operatory porównania - Advanced Bash-Scripting Guide ; i pomyślałem, że powinienem pamiętać, co następuje:
myślałem, że to znaczy „pusty”; ale to oznacza, że „plik istnieje” - służy-e
-z
do testowania pustej zmiennej (ciąg)test
si&&
ich:[ ... ] && [ ... ]
-a
operatora w jednymtest
:[ ... -a ... ]
Oto działające polecenie (przeszukuje wszystkie pliki txt w katalogu i odrzuca te, które
grep
zawierają oba oba słowa):Edytuj 12 sierpnia 2013: powiązana notatka o problemie:
Zauważ, że podczas sprawdzania równości łańcucha za pomocą klasycznego
test
(pojedynczy nawias kwadratowy[
) MUSISZ mieć spację między operatorem „jest równy”, co w tym przypadku jest pojedynczym=
znakiem „równa się” (chociaż dwa znaki równości==
wydają się być akceptowane jako równość operator też). Nie udaje się to (po cichu):... ale dodaj przestrzeń - i wszystko wygląda dobrze:
źródło
((A || B) && C)
?Innym scenariuszem, w którym można uzyskać błąd
[: too many arguments
lub[: a: binary operator expected
błąd, jest próba przetestowania wszystkich argumentów"$@"
Działa poprawnie, jeśli zadzwonisz
foo.sh
lubfoo.sh arg1
. Ale jeśli przekażesz wiele argumentówfoo.sh arg1 arg2
, otrzymasz błędy. Jest tak, ponieważ jest rozwijany do[ -z arg1 arg2 ]
, co nie jest prawidłową składnią.Prawidłowy sposób sprawdzenia istnienia argumentów to
[ "$#" -eq 0 ]
. ($#
to liczba argumentów).źródło
Czasami Jeśli przypadkowo dotkniesz klawiatury i usuniesz spację.
Wywoła ten komunikat o błędzie. Zwróć uwagę, że wymagana jest spacja przed „]”.
źródło
Miałem ten sam problem ze swoimi skryptami. Ale kiedy dokonałem pewnych modyfikacji, zadziałało to dla mnie. Podobało mi się to: -
w ten sposób rozwiązałem mój problem. Mam nadzieję, że ci to pomoże.
źródło