Używanie parametrów w plikach wsadowych w wierszu poleceń systemu Windows

161

W systemie Windows, jak uzyskać dostęp do argumentów przekazywanych podczas uruchamiania pliku wsadowego?

Na przykład, powiedzmy, że mam program o nazwie hello.bat. Kiedy wchodzę hello -aw wierszu poleceń systemu Windows, w jaki sposób mogę powiadomić program, że -azostał przekazany jako argument?

Osoba
źródło
Jak przekazać parametry wiersza poleceń do pliku wsadowego: stackoverflow.com/questions/26551/…
Eric Leschinski
3
Wspomina o „wierszu poleceń DOS”.
David R Tribble

Odpowiedzi:

287

Jak powiedzieli już inni, dostęp do parametrów przekazywanych w wierszu poleceń można uzyskać w plikach wsadowych z notacją %1do %9. Istnieją również dwa inne tokeny, których możesz użyć:

  • %0jest nazwą pliku wykonywalnego (pliku wsadowego) podaną w wierszu poleceń .
  • %*to wszystkie parametry podane w wierszu poleceń - jest to bardzo przydatne, jeśli chcesz przekazać parametry do innego programu.

Istnieje również wiele ważnych technik, o których należy pamiętać, oprócz prostego dostępu do parametrów.

Sprawdzanie, czy parametr został przekazany

Odbywa się to za pomocą konstrukcji takich jak IF "%~1"=="", co jest prawdą wtedy i tylko wtedy, gdy w ogóle nie podano żadnych argumentów. Zwróć uwagę na znak tyldy, który powoduje usunięcie wszystkich otaczających cudzysłowów z wartości %1; bez tyldy otrzymasz nieoczekiwane wyniki, jeśli ta wartość zawiera podwójne cudzysłowy, w tym możliwość wystąpienia błędów składniowych.

Obsługa więcej niż 9 argumentów (lub po prostu ułatwianie życia)

Jeśli potrzebujesz dostępu do więcej niż 9 argumentów, musisz użyć polecenia SHIFT. To polecenie przesuwa wartości wszystkich argumentów o jedno miejsce, tak że %0przyjmuje wartość %1, %1przyjmuje wartość %2itd. %9Przyjmuje wartość dziesiątego argumentu (jeśli jest obecny), który nie był dostępny dla żadnej zmiennej przed wywołaniem SHIFT(enter KomendaSHIFT /? aby uzyskać więcej opcji).

SHIFTprzydaje się również, gdy chcesz łatwo przetwarzać parametry bez wymagania, aby były one prezentowane w określonej kolejności. Na przykład skrypt może rozpoznać flagi -ai -bw dowolnej kolejności. W takich przypadkach dobrym sposobem na przeanalizowanie wiersza poleceń jest

:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!

Ten schemat pozwala analizować dość złożone wiersze poleceń bez popadania w szaleństwo.

Zastąpienie parametrów partii

W przypadku parametrów, które reprezentują nazwy plików, powłoka zapewnia wiele funkcji związanych z pracą z plikami, które nie są dostępne w żaden inny sposób. Dostęp do tej funkcji można uzyskać za pomocą konstrukcji rozpoczynających się od%~ .

Na przykład, aby uzyskać rozmiar pliku przekazanego jako argument, użyj

ECHO %~z1

Aby uzyskać ścieżkę do katalogu, z którego został uruchomiony plik wsadowy (bardzo przydatne!), Możesz użyć

ECHO %~dp0

Pełen zakres tych możliwości można wyświetlić, wpisując CALL /?w wierszu polecenia.

Jon
źródło
4
Konstrukcja: parse,: endparse jest piękna, nawet z GOTO. Dzięki! (Mam na myśli, DOS-BASIC wymusił GOTO)
mmrtnt
1
Ta technika może się nie powieść podczas wywoływania BAT z programu PowerShell. Cytowany argument, taki jak "name=John"będzie name Johnpodczas exe. Aby obejść ten '"name=John"'
problem
1
Jak to się stało bez CALL /?!? Tutaj przez cały czas wpadam na Google.
bigtlb
@Jon Napisałem plik bat, który zawiera tylko jeden kod echo% 1, jeśli wywołam go przez cmd, np. Xx.bat i parametr> „C: \ yy.txt” wywołując plik bat z parametrem i zapisując do pliku txt, ale jeśli podam & w parametrze na początku lub na końcu nie działa. Każdy inny tekst działa poprawnie.
Alex Mathew
56

Używanie parametrów w plikach wsadowych:% 0 i% 9

Pliki wsadowe mogą odnosić się do słów przekazanych jako parametry z tokenami: %0do %9.

%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.

parametry przekazywane w wierszu poleceń muszą być znakami alfanumerycznymi i być oddzielone spacjami. Ponieważ %0jest nazwą programu, tak jak został wywołany, w DOS %0będzie pusty plik AUTOEXEC.BAT, jeśli zostanie uruchomiony w czasie rozruchu.

Przykład:

Umieść następujące polecenie w pliku wsadowym o nazwie mybatch.bat:

@echo off
@echo hello %1 %2
pause

Wywołanie pliku wsadowego w ten sposób: mybatch john billyspowoduje wyświetlenie:

hello john billy

Uzyskaj więcej niż 9 parametrów dla pliku wsadowego, użyj:% *

Token Percent Star %*oznacza „pozostałe parametry”. Możesz użyć pętli for, aby je złapać, jak zdefiniowano tutaj:

http://www.robvanderwoude.com/parameters.php

Uwagi dotyczące ograniczników parametrów partii

Niektóre znaki w parametrach wiersza poleceń są ignorowane przez pliki wsadowe, w zależności od wersji DOS, niezależnie od tego, czy są „chronione”, czy nie, i często w zależności od ich położenia w wierszu poleceń:

commas (",") are replaced by spaces, unless they are part of a string in 
double quotes

semicolons (";") are replaced by spaces, unless they are part of a string in 
double quotes

"=" characters are sometimes replaced by spaces, not if they are part of a 
string in double quotes

the first forward slash ("/") is replaced by a space only if it immediately 
follows the command, without a leading space

multiple spaces are replaced by a single space, unless they are part of a 
string in double quotes

tabs are replaced by a single space

leading spaces before the first command line argument are ignored
Eric Leschinski
źródło
5

Pliki wsadowe automatycznie przekazują tekst po programie, o ile ich zmienne są do przypisania. Są przekazywane w kolejności, w jakiej zostały wysłane; np.% 1 będzie pierwszym napisem wysłanym po wywołaniu programu itp.

Jeśli masz Hello.bat, a zawartość to:

@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause

i wywołujesz partię w poleceniu za pośrednictwem

hello.bat APerson241% date%

powinieneś otrzymać z powrotem tę wiadomość:

Witam, dziękuję APerson241 za uruchomienie tego pliku wsadowego (11.01.2013)

rud3y
źródło
4

@ Jon's :parse/:endparse schemat to świetny początek i ma moją wdzięczność za wstępną przepustkę, ale jeśli myślisz, że torturujący system wsadowy Windows pozwoliłby ci tak łatwo… cóż, przyjacielu, czeka cię szok. Spędziłem cały dzień z tym diabelstwem i po wielu bolesnych badaniach i eksperymentach w końcu udało mi się uzyskać coś realnego do zastosowania w prawdziwym życiu.

Powiedzmy, że chcemy wdrożyć narzędzie foobar. Wymaga początkowego polecenia. Ma opcjonalny parametr, --fooktóry przyjmuje opcjonalną wartość (która oczywiście nie może być innym parametrem); jeśli brakuje wartości, domyślnie default. Ma również opcjonalny parametr, --barktóry przyjmuje wymaganą wartość. Wreszcie może przyjąć flagę --bazbez dozwolonej wartości. Aha, i te parametry mogą przyjść w dowolnej kolejności.

Innymi słowy, wygląda to tak:

foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]

Skomplikowane? Nie, to wydaje się dość typowe dla narzędzi z prawdziwego życia. ( gitktoś?)

Bez zbędnych ceregieli, oto rozwiązanie:

@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson

SET CMD=%~1

IF "%CMD%" == "" (
  GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=

SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
  SHIFT
  IF NOT "%ARG%" == "" (
    IF NOT "%ARG:~0,2%" == "--" (
      SET FOO=%ARG%
      SHIFT
    ) ELSE (
      SET FOO=%DEFAULT_FOO%
    )
  ) ELSE (
    SET FOO=%DEFAULT_FOO%
  )
) ELSE IF "%PARAM%" == "--bar" (
  SHIFT
  IF NOT "%ARG%" == "" (
    SET BAR=%ARG%
    SHIFT
  ) ELSE (
    ECHO Missing bar value. 1>&2
    ECHO:
    GOTO usage
  )
) ELSE IF "%PARAM%" == "--baz" (
  SHIFT
  SET BAZ=true
) ELSE IF "%PARAM%" == "" (
  GOTO endargs
) ELSE (
  ECHO Unrecognized option %1. 1>&2
  ECHO:
  GOTO usage
)
GOTO args
:endargs

ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
  ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
  ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
  ECHO Baz
)

REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof

:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1

Tak, naprawdę jest tak źle. Zobacz mój podobny post na https://stackoverflow.com/a/50653047/421049 , gdzie przedstawiam dokładniejszą analizę tego, co dzieje się w logice i dlaczego użyłem pewnych konstrukcji.

Ohydny. Większość tego musiałem się dzisiaj nauczyć. I to bolało.

Garret Wilson
źródło
3

Użycie zmiennych tj te .BATzmienne i nazywa %0się%9

tohava
źródło