Używam skryptu, który przekazuje argument ciągu i chcę to zrobić, jeśli instrukcja pokazana jest poniżej:
if [ $1 != '' ] && [ $2 != '' ]
then
do something.....
ale to pokazało Error too many argument
. Czemu?
command-line
bash
scripts
taymindis Woon
źródło
źródło
[[ ]]
. W przeciwnym razie musisz podać swoje zmienne.$1
może zostać ustawiony lub zerowany przez użytkownika skryptu. Rozważ tę sekwencję poleceń:$ set '' bar
wówczasecho "x${1}x";
obie zmienne są ustawione, ale jedna z nich jest pusta.Odpowiedzi:
Spróbuj użyć testu -z:
Od człowieka
bash
:źródło
Ponieważ jest to oznaczone
bash
, polecam użyć rozszerzonej konstrukcji testowej ([[...]]
) i zapomnieć o cudzysłowach:O ile nie wybierasz
sh
kompatybilności / POSIX, nie ma powodu, aby nie używać[[ ]]
.źródło
Działa również:
źródło
&&
klasyczne separatory poleceń są niedozwolonetest
. Zamiast tego musisz użyć innych konstrukcji testowych (jak-a
myślę)W przypadku starej wersji odpowiedzi zobacz drugą część tej odpowiedzi. Jeśli chcesz wiedzieć o szczegółach, czytaj dalej
Przyczyna problemu
W samym pytaniu podano, że OP widzi
too many arguments error
, cobash
nie wydaje się , gdy jest testowane :Z
/bin/sh
którym w rzeczywistości jest symlinkowany/bin/dash
na Ubuntu, błąd zgłaszany w następujący sposób:A samodzielny
/bin/test
również:Sidenote: Jeśli zastanawiasz się, co to jest
/usr/bin/test
i dlaczego używambash
ish
, to powinniście wiedzieć, że[
jest alias dlatest
komendy, która występuje także jako samodzielny plik wykonywalny lub częściej - jak skorupy wbudowany w którym to, co każda powłoka użyje pierwszy . Jeśli chodzi oif
instrukcje, operują one na statusach wyjściowych poleceń, stąd polecenia[
itest
są, a wszystko inne jest argumentem tych poleceń - niewłaściwa kolejność tych argumentów wiersza poleceń prowadzi do błędów.Powrót do tematu: nie jest jasne, w jaki sposób OP otrzymał niepowiązany błąd. Jednak we wszystkich 3 przypadkach problem jest taki sam - zmienna nieuzbrojona będzie traktowana jako pusta, dlatego to, co powłoka widzi z tymi niecytowanymi zmiennymi, to
który łamie składnię, która
test
rozumie. Pamiętasz, co powiedziałem o niewłaściwej kolejności argumentów wiersza poleceń? Dlatego dlaczego cytowanie jest ważne. Włączmy dane diagnostyczne i zobaczmy, co wykonuje powłoka:Lepszy sposób testowania nieuzbrojonych zmiennych
Bardzo częstym podejściem jest:
Cytując Gillesa :
Prawdopodobnie powinno to być dość przenośne, ponieważ widziałem je w
/bin/sh
skryptach. Można go również łączyć jak wOczywiście moglibyśmy użyć
-z
flagi, jednak według badań niektórych pocisków, szczególnie ksh88 (według Stephane Chazelas ), flaga ta jest wadliwa.Zobacz też
\[
vs\[\[
vs((
źródło
Myślę, że tytuł postu jest niepoprawny, ponieważ celem wiadomości było sprawdzenie, czy 1 i 2 USD nie są zerowe. W podanym przykładzie brakowało podwójnych cudzysłowów w 1 USD i 2 USD do pracy. Zmienne muszą być podwójnie cytowane, aby można je było rozwinąć podczas porównywania ciągów. Ale sprawdzenie, czy istnieje 1 USD i 2 USD, jest tym samym, co sprawdzenie, czy 2 USD istnieje, ponieważ nie może istnieć, jeśli 1 USD nie istnieje. W tym przypadku nie jest również potrzebne polecenie „if”, ponieważ „test” zwraca wartość true / false i używa „&&” jako „następnie”, jeśli return wynosi 0 / true:
Prostsze, z -n (niezerową):
Aby „sprawdzić, czy 1 $ i 2 $ są zerowe” byłoby to samo, co sprawdzenie, czy nie ma parametru:
źródło