Verwenden von Parametern in Batchdateien in der Windows-Befehlszeile

160

Wie greifen Sie unter Windows auf Argumente zu, die beim Ausführen einer Batchdatei übergeben wurden?

Nehmen wir zum Beispiel an, ich habe ein Programm mit dem Namen hello.bat. hello -aWie kann ich meinem Programm bei der Eingabe über eine Windows-Befehlszeile mitteilen, dass dies -aals Argument übergeben wurde?

Eine Person
quelle
So übergeben Sie Befehlszeilenparameter an eine Batchdatei: stackoverflow.com/questions/26551/…
Eric Leschinski
3
Er erwähnt "DOS-Befehlszeile".
David R Tribble

Antworten:

286

Wie bereits erwähnt, kann auf Parameter, die über die Befehlszeile übergeben werden, in Batchdateien mit der Notation %1to zugegriffen werden %9. Es gibt auch zwei andere Token, die Sie verwenden können:

  • %0ist der Name der ausführbaren Datei (Batchdatei), wie in der Befehlszeile angegeben .
  • %*sind alle in der Befehlszeile angegebenen Parameter - dies ist sehr nützlich, wenn Sie die Parameter an ein anderes Programm weiterleiten möchten.

Neben dem einfachen Zugriff auf die Parameter sind auch viele wichtige Techniken zu beachten.

Überprüfen, ob ein Parameter übergeben wurde

Dies geschieht mit Konstrukten wie IF "%~1"=="", was genau dann zutrifft, wenn überhaupt keine Argumente übergeben wurden. Beachten Sie das Tilde-Zeichen, das dazu führt, dass umgebende Anführungszeichen aus dem Wert von entfernt werden %1. Ohne Tilde erhalten Sie unerwartete Ergebnisse, wenn dieser Wert doppelte Anführungszeichen enthält, einschließlich der Möglichkeit von Syntaxfehlern.

Umgang mit mehr als 9 Argumenten (oder einfach das Leben leichter machen)

Wenn Sie auf mehr als 9 Argumente zugreifen müssen, müssen Sie den Befehl verwenden SHIFT. Dieser Befehl verschiebt die Werte aller Argumente um eine Stelle, sodass %0der Wert von %1, %1der Wert von %2usw. %9den Wert des zehnten Arguments (falls vorhanden) annimmt, das vor dem Aufruf SHIFT(enter) über keine Variable verfügbar war Befehl SHIFT /?für weitere Optionen).

SHIFTDies ist auch nützlich, wenn Sie Parameter einfach verarbeiten möchten, ohne dass sie in einer bestimmten Reihenfolge angezeigt werden müssen. Zum Beispiel kann ein Skript , um die Fahnen erkennt -aund -bin beliebiger Reihenfolge. Eine gute Möglichkeit, die Befehlszeile in solchen Fällen zu analysieren, ist

: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!

Mit diesem Schema können Sie ziemlich komplexe Befehlszeilen analysieren, ohne verrückt zu werden.

Ersetzung von Chargenparametern

Für Parameter, die Dateinamen darstellen, bietet die Shell zahlreiche Funktionen für die Arbeit mit Dateien, auf die auf keine andere Weise zugegriffen werden kann. Auf diese Funktionalität wird mit Konstrukten zugegriffen, die mit beginnen %~.

Verwenden Sie beispielsweise, um die Größe der als Argument übergebenen Datei zu ermitteln

ECHO %~z1

Um den Pfad des Verzeichnisses abzurufen, von dem aus die Batchdatei gestartet wurde (sehr nützlich!), Können Sie verwenden

ECHO %~dp0

Sie können den gesamten Bereich dieser Funktionen anzeigen, indem Sie CALL /?die Eingabeaufforderung eingeben .

Jon
quelle
4
Das Konstrukt: parse ,: endparse ist Schönheit, auch mit dem GOTO. Vielen Dank! (Ich meine, die DOS-BASIC hat GOTO gezwungen)
mmrtnt
1
Diese Technik kann fehlschlagen, wenn die BVT von Powershell aufgerufen wird. Ein zitiertes Argument wie "name=John"wird name Johnwährend exe. Eine Problemumgehung besteht darin, mit einfachen Anführungszeichen zu umgeben,'"name=John"'
cmcginty
1
Wie bin ich so lange ohne gegangen CALL /?!? Hier habe ich die ganze Zeit mit Google rumgespielt.
Bigtlb
@Jon Ich habe eine Bat-Datei geschrieben, die nur ein Code-Echo% 1 enthält, wenn ich sie über cmd aufrufe, z. B. xx.bat & parameter> "C: \ yy.txt", die Bat-Datei mit Parameter aufruft und in die TXT-Datei schreibt, aber wenn ich & gebe im Parameter am Anfang oder Ende funktioniert es nicht. Jeder andere Text funktioniert einwandfrei.
Alex Mathew
56

Verwenden von Parametern in Batchdateien:% 0 und% 9

Batch-Dateien können sich auf die Wörter beziehen, die als Parameter mit den Token übergeben wurden: %0to %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.

In der Befehlszeile übergebene Parameter müssen alphanumerische Zeichen sein und durch Leerzeichen getrennt sein. Da %0der Programmname so ist, wie er aufgerufen wurde, ist er unter DOS %0für AUTOEXEC.BAT leer, wenn er beim Booten gestartet wird.

Beispiel:

Fügen Sie den folgenden Befehl in eine Batchdatei mit dem Namen ein mybatch.bat:

@echo off
@echo hello %1 %2
pause

Das Aufrufen der Batch-Datei lautet wie folgt: mybatch john billywürde Folgendes ausgeben:

hello john billy

Holen Sie sich mehr als 9 Parameter für eine Batch-Datei, verwenden Sie:% *

Der Percent Star-Token %*bedeutet "den Rest der Parameter". Sie können eine for-Schleife verwenden, um sie zu erfassen, wie hier definiert:

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

Hinweise zu Trennzeichen für Stapelparameter

Einige Zeichen in den Befehlszeilenparametern werden von Batchdateien ignoriert, abhängig von der DOS-Version, ob sie "maskiert" sind oder nicht, und häufig abhängig von ihrer Position in der Befehlszeile:

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
quelle
5

Batch-Dateien übergeben den Text automatisch nach dem Programm, sofern es sich um Variablen handelt, denen sie zugewiesen werden sollen. Sie werden in der Reihenfolge übergeben, in der sie gesendet werden. zB% 1 ist die erste Zeichenfolge, die nach dem Aufruf des Programms usw. gesendet wird.

Wenn Sie Hello.bat haben und der Inhalt ist:

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

und Sie rufen den Batch-in-Befehl über auf

hello.bat APerson241% date%

Sie sollten diese Nachricht zurückerhalten:

Hallo, APerson241, danke, dass Sie diese Batch-Datei ausgeführt haben (11.01.2013)

rud3y
quelle
4

@ Jons :parse/ :endparseSchema ist ein großartiger Start, und er ist mir für den ersten Durchgang dankbar, aber wenn Sie glauben, dass das quälende Windows-Batch-System Sie so einfach davon abhalten würde ... nun, mein Freund, stehen Sie vor einem Schock. Ich habe den ganzen Tag mit dieser Teufelei verbracht, und nach vielen schmerzhaften Nachforschungen und Experimenten habe ich endlich etwas geschafft, das für einen realen Nutzen brauchbar ist.

Nehmen wir an, wir möchten ein Dienstprogramm implementieren foobar. Es erfordert einen ersten Befehl. Es hat einen optionalen Parameter, --fooder einen optionalen Wert annimmt (der natürlich kein anderer Parameter sein kann). Wenn der Wert fehlt, wird standardmäßig verwendet default. Es hat auch einen optionalen Parameter, --barder einen erforderlichen Wert annimmt. Schließlich kann ein Flag --bazohne zulässigen Wert verwendet werden. Oh, und diese Parameter können in beliebiger Reihenfolge kommen.

Mit anderen Worten, es sieht so aus:

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

Kompliziert? Nein, das scheint ziemlich typisch für echte Versorgungsunternehmen zu sein. ( gitjemand?)

Hier ist ohne weiteres eine Lösung:

@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

Ja, es ist wirklich so schlimm. Siehe meinen ähnlichen Beitrag unter https://stackoverflow.com/a/50653047/421049 , in dem ich genauer analysiere, was in der Logik vor sich geht und warum ich bestimmte Konstrukte verwendet habe.

Schrecklich. Das meiste musste ich heute lernen. Und es tat weh.

Garret Wilson
quelle
3

Verwenden Sie Variablen, dh die .BATVariablen und rufen Sie %0auf%9

tohava
quelle