Mój system operacyjny to Windows Vista. Potrzebuję pliku „.bat”, w którym muszę sprawdzić, czy użytkownik wprowadza parametr wiersza polecenia, czy nie. Jeśli tak, to jeśli parametr jest równy -b
, zrobię coś, w przeciwnym razie oflaguję „Invalid input”. Jeśli użytkownik nie poda żadnego parametru wiersza poleceń, coś zrobię. Utworzyłem następujący plik .bat. Działa dla przypadków -b
i nie jest równy -b
- ale kończy się niepowodzeniem, gdy użytkownik nie przekazuje żadnego parametru wiersza polecenia.
Zawsze otrzymuję błąd:
GOTO was unexpected at this time.
Czy ktoś może mi powiedzieć, co ja tu robię źle?
ECHO OFF
CLS
ECHO.
IF [%1]==[/?] GOTO BLANK
IF %1=="-b" GOTO SPECIFIC
IF NOT %1=="-b" GOTO UNKNOWN
:SPECIFIC
ECHO SPECIFIC
GOTO DONE
:BLANK
ECHO No Parameter
GOTO DONE
:UNKNOWN
ECHO Unknown Option
GOTO DONE
:DONE
ECHO Done!
windows
file
batch-file
cmd
javauser71
źródło
źródło
GOTO BLANK
wierszu) do pozostałych dwóchIF
instrukcji, czy to rozwiąże problem?Odpowiedzi:
Musisz sprawdzić, czy parametr jest pusty:
if "%~1"=="" goto blank
Gdy już to zrobisz, włącz if / else -b:
if "%~1"=="-b" (goto specific) else goto unknown
Otaczanie parametrów cudzysłowami ułatwia sprawdzanie elementów takich jak puste / puste / brakujące parametry. "~" zapewnia, że podwójne cudzysłowy są usuwane, jeśli były w argumencie wiersza poleceń.
źródło
File
, w takim przypadku powinieneś sprawdzać tylkoexist
lubnot exist
. Dlatego twoje argumenty powinny być dobrze zdefiniowane lub po prostu użyj PowerShell lub vbScript (jeśli jesteś w latach 80-tych ...)run.bat "a b"
."%1"==""
ulega awarii, jeśli argument ma spację. Zobacz stackoverflow.com/a/46942471Poszukaj odpowiedzi na http://ss64.com/nt/if.html ; polecenie jest
IF [%1]==[] GOTO NO_ARGUMENT
lub podobne.źródło
"%1"==""
. Muszę to rozwinąć w mojej własnej odpowiedzi.foo.bat "1st parameter" 2nd_param
. Zobacz stackoverflow.com/questions/2541767/…[%1]==[-b]
nie będzie pasować, jeśli argument jest cytowany. Przykładrun.bat "-b"
. Zobacz stackoverflow.com/a/46942471Krótka odpowiedź - użyj nawiasów kwadratowych:
lub (jeśli potrzebujesz obsługiwać cytowane argumenty, zobacz Edycję poniżej):
Czemu? możesz zapytać. Cóż, tak jak wspomniał Jeremiah Willcock: http://ss64.com/nt/if.html - używają tego! OK, ale co jest nie tak z cudzysłowami?
Ponownie, krótka odpowiedź: są „magiczne” - czasami podwójne (podwójne) cudzysłowy są zamieniane na pojedynczy (podwójny) cudzysłów. I na początek muszą pasować.
Rozważ ten mały skrypt:
Przetestujmy to:
Wydaje się działać. Ale teraz przejdźmy na drugi bieg:
Boom To nie zostało ocenione jako prawda, ani też nie zostało ocenione jako fałszywe. Skrypt ZMARŁ. Jeśli miałbyś wyłączyć reaktor gdzieś na linii, cóż - pech. Umrzesz teraz jak Harry Daghlian.
Możesz pomyśleć - OK, argumenty nie mogą zawierać cudzysłowów. Jeśli tak, to się dzieje. Źle Oto pociecha:
O tak. Nie martw się - czasem to będzie działać.
Wypróbujmy inny skrypt:
Możesz sam sprawdzić, czy w powyższych przypadkach działa poprawnie. To logiczne - cudzysłowy nie mają nic wspólnego z nawiasami, więc nie ma tu magii. Ale co z doprawieniem argumentów nawiasami?
Nie ma szczęścia. Nawiasy po prostu nie mogą zablokować
cmd.exe
parsera.Wróćmy na chwilę do złych cytatów. Problem pojawił się, gdy argument kończył się cytatem:
Co jeśli zdam tylko:
Skrypt w ogóle się nie uruchomi. To samo dotyczy
args.bat
:Ale co otrzymam, gdy liczba
"
-znaków „pasuje” (czyli - jest parzysta), w takim przypadku:MIŁE - mam nadzieję, że nauczyłeś się czegoś o tym, jak
.bat
pliki dzielą swoje argumenty wiersza poleceń (WSKAZÓWKA: * To nie jest dokładnie tak, jak w bashu). Powyższy argument zawiera spację. Ale cytaty nie są usuwane automatycznie.A argq? Jak to na to reaguje? Przewidywalnie:
A więc - pomyśl, zanim powiesz: „Wiesz co? Po prostu używaj cudzysłowów. [Bo dla mnie to wygląda ładniej]”.
Edytować
Niedawno pojawiły się komentarze na temat tej odpowiedzi - cóż, nawiasy kwadratowe „nie radzą sobie” z przekazywaniem cytowanych argumentów i traktowaniem ich tak, jakby nie były cytowane.
Składnia:
Nie jest jakąś nowo odkrytą zaletą podwójnych cudzysłowów, ale przejawem zgrabnej funkcji usuwania cudzysłowów ze zmiennej argumentu, jeśli pierwszy i ostatni znak jest cudzysłowem podwójnym.
Ta „technologia” działa równie dobrze w przypadku nawiasów kwadratowych:
Warto było zwrócić na to uwagę, więc głosuję również za nową odpowiedzią.
Wreszcie, fani podwójnych cudzysłowów, czy
""
w waszej książce istnieje argument w formie , czy jest on pusty? Tylko pytam' ;)źródło
[%1]==[-b]
nie będą pasować, jeśli argument będzie cytowany jakrun.bat "-b"
. Zobacz stackoverflow.com/a/46942471[%1]==[-b]
i"%1"=="-b"
były takie same dla skryptów wsadowych systemów MS / PC-DOS pod Windows 98 i wcześniejszych. Odkąd w Win 2000 / NT wprowadzono składnię, wif "%~1"=="-b"
której podwójne cudzysłowy mają specjalne znaczenie, jest to sposób, w jaki należy kodować skrypty, ponieważ zapewnia bardziej solidną ochronę. Podwójne cudzysłowy zmieniają znaczenie znaków specjalnych (spróbuj & | i% znaków w linii poleceń). 99,9% przykładów działa ze składnią podwójnych cudzysłowów - w Twoim przykładzieargq bla2" "bla3
jest tylko wielkość liter, aby uzasadnić nawiasy kwadratowe. Umieszczone podwójne cudzysłowy to przepis na katastrofę - wystarczy powiedziećcmd
powłoce. W innych systemach można czasem zacytować wszystko, łącznie ze znakiem NUL. ( stackoverflow.com/questions/2730732/… ) - to pytanie właśnie się pokazuje, trzeba użyć jakiegoś zewnętrznego programu.Oprócz innych odpowiedzi, które subskrybuję, możesz rozważyć użycie
/I
przełącznikaIF
polecenia.może to być pomocne, jeśli chcesz zapewnić użytkownikom elastyczność bez rozróżniania wielkości liter przy określaniu parametrów.
źródło
Porównujesz struny. Jeśli argumenty zostaną pominięte,
%1
interpretowane jest jako puste, więc polecenia stają sięIF =="-b" GOTO SPECIFIC
na przykład (co jest błędem składniowym). Zawiń swoje ciągi w cudzysłów (lub nawiasy kwadratowe).źródło
Właściwie wszystkie inne odpowiedzi mają wady. Najbardziej niezawodny sposób to:
Szczegółowe wyjaśnienie:
Użycie
"%1"=="-b"
spowoduje załatwienie awarii przy przekazywaniu argumentów spacjami i cudzysłowami. To najmniej niezawodna metoda.Używanie
[%1]==[-b]
jest lepsze, ponieważ nie spowoduje awarii ze spacjami i cudzysłowami, ale nie będzie pasować, jeśli argument jest otoczony cudzysłowami.Używanie
"%~1"=="-b"
jest najbardziej niezawodne.%~1
usunie otaczające cudzysłowy, jeśli istnieją. Działa więc z cudzysłowami i bez cudzysłowów, a także bez argumentów.źródło
IF [%~1]==[]
- to działa, a nawet obsługuje"-b"
. Musisz tylko umieć myśleć wewnątrz pudełka, erm, kwadratu [nawiasy].Ostatnio zmagałem się z implementacją złożonych przełączników parametrów w pliku wsadowym, więc oto wynik moich badań. Żadna z udzielonych odpowiedzi nie jest w pełni bezpieczna, przykłady:
"%1"=="-?"
nie będzie pasował, jeśli parametr jest ujęty w cudzysłowy (wymagane w przypadku nazw plików itp.) lub ulegnie awarii, jeśli parametr jest w cudzysłowach i ma spacje (często spotykane w nazwach plików)Dowolna kombinacja z nawiasami kwadratowymi
[%1]==[-?]
lub[%~1]==[-?]
zakończy się niepowodzeniem, jeśli parametr zawiera spacje w cudzysłowach:Proponowane najbezpieczniejsze rozwiązanie
"%~1"=="-?"
ulegnie awarii ze złożonym parametrem, który zawiera tekst poza cudzysłowami i tekst ze spacjami w cudzysłowie:Jedynym sposobem, aby upewnić się, że wszystkie powyższe scenariusze są uwzględnione, jest użycie EnableDelayedExpansion i przekazanie parametrów przez odwołanie (nie przez wartość) przy użyciu zmiennych. Wtedy nawet najbardziej złożony scenariusz będzie działał dobrze:
źródło
W tym celu partia systemu Windows ma słowo kluczowe DEFINED.
źródło