Mój plik bat musi akceptować wiele opcjonalnych nazwanych argumentów.
mycmd.bat man1 man2 -username alice -otheroption
Na przykład moje polecenie ma 2 obowiązkowe parametry i dwa opcjonalne parametry (-username), które ma wartość argumentu alicja i -otheroption:
Chciałbym móc wstawić te wartości do zmiennych.
Po prostu dzwonię do każdego, kto już to rozwiązał. Człowieku, te nietoperze są uciążliwe.
batch-file
ciastko z kurczaka
źródło
źródło
http://web.archive.org/web/20090403050231/http://www.pcguide.com/vb/showthread.php?t=52323
.Odpowiedzi:
Chociaż zwykle zgadzam się z komentarzem @AlekDavis , jest kilka sposobów, aby to zrobić w powłoce NT.
Podejście skorzystałbym z polecenia SHIFT i rozgałęzienia warunkowego IF , coś takiego ...
źródło
SHIFT /2
przesunięcia rozpoczynające się od arg 2. Nie przesuwa się dwa razy. Czy nie należy go zastąpićSHIFT & SHIFT
?mycmd.bat -username anyvalue -username myName -otheroption othervalue
. Wynik powinien mieć postać user = myName, other = othervalue; ale kod daje user = -username, other = othervalue. Błąd jest ustalana poprzez zastąpienieSHIFT /2
zSHIFT & SHIFT
.;
- nie można go używać zamiast&
.%1
i%2
zostały „użyte”. b) PojedynczySHIFT
w linii 11 przesuwa wartość o%2
1 pozycję w dół i jest następnie dostępny (ponownie) jako%1
, a wartość „Nieużywane”%3
jest dostępna jako%2
. c) WIF
wierszu 13 widzimy tę już „Użytą” wartość, z%2
której jest teraz w%1
. d) Jeśli "nazwa użytkownika" z linii 10 będzie wyglądać"-otheroption"
, zostanie użyta ponownie iother
zostanie ustawiona na nową wartość w%2
, która prawdopodobnie była nazwą następnej opcji. --->-otheroption
nie następowała wartość, więc prawdopodobnie była ona pomyślana jako-Flag
opcja typu i nie powinna zużywać drugiego argumentu. Po trzecie: Jeśli argument%1
nie jest obsługiwany przez instrukcje wewnętrzneIF
, jest po cichu ignorowany. Kod powinien prawdopodobnie wyświetlić komunikat wskazujący, że nie była to prawidłowa opcja. Można to zrobić, dodając wymagane instrukcjeSHIFT
iGOTO :loop
do instrukcji wewnętrznychIF
lub dodającELSE
instrukcję.Wybrana odpowiedź działa, ale przydałaby się pewna poprawa.
Moje rozwiązanie polega na utworzeniu zmiennej OPTIONS, która definiuje wszystkie opcje i ich wartości domyślne. OPCJE są również używane do testowania, czy podana opcja jest prawidłowa. Ogromna ilość kodu jest zapisywana po prostu poprzez przechowywanie wartości opcji w zmiennych o takich samych nazwach jak opcja. Ilość kodu jest stała, niezależnie od liczby zdefiniowanych opcji; musi się zmienić tylko definicja OPTIONS.
EDYCJA - Ponadto kod pętli: musi ulec zmianie, jeśli zmieni się liczba obowiązkowych argumentów pozycyjnych. Na przykład, często wszystkie argumenty są nazwane, w takim przypadku chcesz przeanalizować argumenty zaczynające się od pozycji 1 zamiast 3. Zatem w pętli: wszystkie 3 stają się 1, a 4 staje się 2.
Naprawdę nie ma tak dużo kodu. Większość powyższego kodu to komentarze. Oto dokładnie ten sam kod, bez komentarzy.
To rozwiązanie zapewnia argumenty w stylu uniksowym w ramach wsadu systemu Windows. Nie jest to norma dla systemu Windows - batch zwykle ma opcje poprzedzające wymagane argumenty, a opcje są poprzedzone przedrostkiem
/
.Techniki zastosowane w tym rozwiązaniu można łatwo dostosować do stylu opcji systemu Windows.
%1
i kontynuuje, dopóki arg 1 nie zacznie się od/
/
.SET /VAR=VALUE
nieSET "/VAR=VALUE"
działa. I tak już to robię w moim rozwiązaniu./
. To ograniczenie można wyeliminować, stosując niejawnie zdefiniowaną//
opcję, która służy jako sygnał do wyjścia z pętli analizowania opcji. Nic nie zostanie zapisane dla//
„opcji”.Aktualizacja 2015-12-28: Wsparcie dla
!
wartości opcjiW powyższym kodzie każdy argument jest rozwijany, podczas gdy opóźnione rozwijanie jest włączone, co oznacza, że
!
najprawdopodobniej jest usuwany lub coś podobnego!var!
jest rozwijane. Ponadto^
można go usunąć, jeśli!
jest obecny. Następująca mała modyfikacja kodu bez komentarza usuwa takie ograniczenie!
i^
jest zachowywana w wartościach opcji.źródło
Jeśli chcesz używać argumentów opcjonalnych, ale nie nazwanych, to takie podejście zadziałało. Myślę, że jest to znacznie łatwiejszy kod do naśladowania.
źródło
IF "%1"==""
zakończy się niepowodzeniem, jeśli argument zawiera sam cudzysłów. Po prostu użyj innego, nie specjalnego symbolu, na przykład ._ = [] # etcTworzenie zmiennych dynamicznych
Plusy
%1
,%2
...%*
w takt/arg
i na-arg
stylCons
setlocal
do lokalnego określania zakresu lub napisz towarzyszącą:CLEAR-ARGS
procedurę!--force
to-f
)""
wsparcia dla pustych argumentówStosowanie
Oto przykład, jak następujące argumenty odnoszą się do zmiennych .bat:
Realizacja
źródło
:ARG-PARSER
procedury do zewnętrznego pliku .bat, takarg-parser.bat
aby była dostępna także dla innych skryptów.Kiedyś napisałem program, który obsługuje krótkie (-h), długie (--help) i nie będące opcjami argumenty w pliku wsadowym. Techniki te obejmują:
argumenty nie będące opcjami, po których następują argumenty opcji.
operator przesunięcia dla tych opcji, które nie mają argumentów, takich jak „--help”.
operator dwóch przesunięć czasowych dla tych opcji, które wymagają argumentu.
pętla po etykiecie do przetwarzania wszystkich argumentów wiersza poleceń.
Zamknij skrypt i zatrzymaj przetwarzanie dla tych opcji, które nie wymagają dalszych działań, takich jak „--help”.
Napisałem funkcje pomocy dla kierowania użytkownikami
Oto mój kod.
źródło
Oto parser argumentów. Możesz mieszać dowolne argumenty łańcuchowe (pozostawione nietknięte) lub opcje ze zmianą znaczenia (pojedyncze lub pary opcja / wartość). Aby to przetestować, odkomentuj ostatnie 2 instrukcje i uruchom jako:
Znak ucieczki jest zdefiniowany jako
"_SEP_=/"
, w razie potrzeby przedefiniuj.źródło