1437 Stimmen

Wie kann ich Argumente an eine Batch-Datei übergeben?

Ich muss eine ID und ein Kennwort zum Zeitpunkt der Ausführung an eine Stapeldatei übergeben, anstatt sie fest in die Datei zu kodieren.

So sieht die Befehlszeile aus:

test.cmd admin P@55w0rd > test-log.txt

9 Stimmen

Zum "ganzen Rest" siehe den Kommentar von Greg Hegill unter Wie erhalte ich die Parameter einer Batchdatei ab der n-ten Position?

0 Stimmen

Ich habe ein Umgebungsstartskript, das meinen Benutzernamen und mein Passwort in Umgebungsvariablen überträgt, damit ich sie nicht jedes Mal neu eingeben muss... Ich benutze die meiste Zeit Bash (Linux, Mac und Windows), und muss es für Proxy-Konfigurationen in Skripten usw. für die Arbeit verwenden.

1286voto

Greg Hewgill Punkte 882617

Ein weiterer nützlicher Tipp ist die Verwendung von %* für "alle". Zum Beispiel:

echo off
set arg1=%1
set arg2=%2
shift
shift
fake-command /u %arg1% /p %arg2% %*

Wenn Sie laufen:

test-command admin password foo bar

wird die obige Batch-Datei ausgeführt:

fake-command /u admin /p password admin password foo bar

Möglicherweise ist die Syntax nicht ganz korrekt, aber das ist die allgemeine Idee.

149 Stimmen

%* dehnt sich auf alle Parameter aus, unabhängig von der Verschiebung. Selbst nach den beiden Verschiebungen hätten Sie also noch die ersten beiden Argumente in %*. Sie können etwas wie dies verwenden: stackoverflow.com/questions/761615/ um eine Variable zu erhalten, die alles außer den ersten n Parametern enthält.

2 Stimmen

Bitte beachten Sie, dass %* nicht überall funktioniert! Zum Beispiel funktioniert es nicht mit DOSBox 0.73 (vielleicht ist das ein Fehler, der gemeldet werden sollte).

37 Stimmen

Es ist kein Fehler, denn %* hat unter MS-DOS oder Win9x nie funktioniert.

358voto

Keng Punkte 49933

Ich habe es folgendermaßen gemacht:

@fake-command /u %1 /p %2

So sieht der Befehl aus:

test.cmd admin P@55w0rd > test-log.txt

El %1 gilt für den ersten Parameter der %2 (und jetzt kommt der knifflige Teil) gilt für den zweiten. Sie können bis zu 9 Parameter auf diese Weise übergeben.

20 Stimmen

Wenn du so dumm bist wie ich, hat dein Verstand nach echo %1 %2 und wurde durch den nicht ausschneid- und einfügbaren einfachsten Fall mit einer @ und eine fake-command mit params, weil wir dachten, wir bekämen fake-command.bat (in diesem Fall wird die überkomplizierte fake-command.bat haben könnte echo %2 %4 um die Parameternamen zu ignorieren). Falsch, Dummkopf. TL;DR: Seien Sie nicht so dumm wie ich. 1. echo echo %1 %2 > test.bat 2. test word1 word2 . 3. Gewinn.

7 Stimmen

Fünf Jahre später lese ich meinen Kommentar wieder mit Verwirrung. Ich meinte wohl "um eine .bat mit zwei Parametern zu erstellen, geben Sie buchstäblich echo echo %1 %2 > test.bat . Die Datei test.bat enthält echo %1 %2 (Sie hätten sie auch in einem Texteditor speichern können). Geben Sie nun test word1 word2 anrufen und sehen, dass die Parameter funktionieren. word1 word2 wird in der Befehlszeile ausgegeben. ( echo %2 %4 würde ignoriert haben /u y /p Sie hätten also anrufen können test /u word1 /p word2 um das gleiche Ergebnis zu erzielen). @ vor einem cmd in einer Bat-Datei bedeutet, dass der cmd nicht wiederholt wird.

1 Stimmen

Möglicherweise möchten Sie auch einige Anführungszeichen behandeln/schützen, z.B: SetLocal Set dbName=%1 Rem dbName If Not Defined dbName Goto SyntaxErr REM Remove all (/any) the quotes Set dbName=%dbName:"=% If "%dbName%" == "" Goto SyntaxErr

177voto

thelsdj Punkte 8804

Wenn Sie fehlende Parameter auf intelligente Weise behandeln wollen, können Sie etwas wie folgt tun:

IF %1.==. GOTO No1
IF %2.==. GOTO No2
... do stuff...
GOTO End1

:No1
  ECHO No param 1
GOTO End1
:No2
  ECHO No param 2
GOTO End1

:End1

4 Stimmen

Welche Bedeutung haben Punkt/Periode bei diesen Gleichheitsoperationen?

11 Stimmen

Wenn %1 leer ist, wird dies als IF . == . enden, und so wird das GOTO passieren. Wir verwenden hier also x: IF x%1 == x -> IF x==x -> true

3 Stimmen

Sie sollten sich fragen, welchen Wert ein "unprovided argument" hat? Wogegen sollte man ein "unprovided argument" prüfen? Wenn Sie dann keine Antwort haben, sollten Sie einen Trick wie den der Punkte anwenden. Denken Sie daran, dass, wie hier angegeben ss64.com/nt/if.html "Man kann eigentlich fast jedes Zeichen dafür verwenden, ein '~' oder geschweifte Klammern, { } oder sogar die Zahl 4, aber eckige Klammern werden oft gewählt, weil sie keine besondere Bedeutung haben."

102voto

jeb Punkte 74279

Der Zugriff auf Chargenparameter kann einfach mit %1, %2, ... %9 oder auch %* erfolgen,
aber nur, wenn der Inhalt einfach ist.

Es gibt keinen einfachen Weg für komplexe Inhalte wie "&"^& da es nicht möglich ist, auf %1 zuzugreifen, ohne einen Fehler zu erzeugen.

set  var=%1
set "var=%1"
set  var=%~1
set "var=%~1"

Die Zeilen erweitern sich zu

set  var="&"&
set "var="&"&"
set  var="&"&
set "var="&"&"

Und jede Zeile schlägt fehl, da eine der & steht außerhalb der Anführungszeichen.

Es kann mit dem Lesen aus einer temporären Datei gelöst werden. bemerkte Version des Parameters.

@echo off
SETLOCAL DisableDelayedExpansion

SETLOCAL
for %%a in (1) do (
    set "prompt="
    echo on
    for %%b in (1) do rem * #%1#
    @echo off
) > param.txt
ENDLOCAL

for /F "delims=" %%L in (param.txt) do (
  set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo %%1 is '!param1!'

Der Trick besteht darin, die echo on und erweitern Sie das %1 nach einem rem Anweisung (funktioniert auch mit %2 .. %* ).
Also auch "&"& ohne einen Fehler zu produzieren, wie es angemerkt wird.

Um jedoch die Ausgabe der echo on benötigen Sie die beiden for-Schleifen.

Die zusätzlichen Zeichen * # werden verwendet, um sich gegen Inhalte wie /? (würde die Hilfe für REM ).
Oder ein Caret ^ am Zeilenende könnte als mehrzeiliges Zeichen funktionieren, auch nach einem rem .

Dann lesen Sie die rem-Parameter Ausgabe aus der Datei, aber vorsichtig.
Das FOR /F sollte bei ausgeschalteter verzögerter Expansion funktionieren, da sonst Inhalte mit "!" zerstört würden.
Nach dem Entfernen der zusätzlichen Zeichen in param1 haben Sie es.

Und zu verwenden param1 auf sichere Art und Weise die verzögerte Expansion ermöglichen.

0 Stimmen

For /F "tokens=*" %%a in ('echo %*') do set "all_args=%%a"

1 Stimmen

@KevinEdwards Dann versuchen Sie es mit einem & Ihre Lösung funktioniert nur bei einfachen Inhalten

1 Stimmen

@KevinEdwards Ich habe es getestet, test.bat ^& und es scheitert. Nur test.bat "&" funktioniert, aber das war nicht mein Punkt. Sie können nicht verwenden %* , %1 auf sichere Weise ohne REM-Technik

73voto

kodybrown Punkte 2087

Ein Freund hat mich vor kurzem nach diesem Thema gefragt, also dachte ich, ich poste mal, wie ich mit Befehlszeilenargumenten in Batch-Dateien umgehe.

Wie Sie sehen werden, hat diese Technik einen gewissen Overhead, aber sie macht meine Batch-Dateien sehr leicht verständlich und schnell zu implementieren. Außerdem unterstützt sie die folgenden Strukturen:

>template.bat [-f] [--flag] [--namedvalue value] arg1 [arg2][arg3][...]

Das Wichtigste ist, dass die :init , :parse y :main Funktionen.

Beispiel für die Verwendung

template.bat /? test v1.23 This is a sample batch file template, providing command-line arguments and flags.

USAGE:
test.bat [flags] "required argument" "optional argument"

/?, --help           shows this help
/v, --version        shows the version
/e, --verbose        shows detailed output
-f, --flag value     specifies a named parameter value

>template.bat          <- throws missing argument error
(same as /?, plus..)
****                                   ****
****    MISSING "REQUIRED ARGUMENT"    ****
****                                   ****

>template.bat -v
1.23

>template.bat --version
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

>template.bat -e arg1
**** DEBUG IS ON
UnNamedArgument:    "arg1"
UnNamedOptionalArg: not provided
NamedFlag:          not provided

>template.bat --flag "my flag" arg1 arg2
UnNamedArgument:    "arg1"
UnNamedOptionalArg: "arg2"
NamedFlag:          "my flag"

>template.bat --verbose "argument #1" --flag "my flag" second
**** DEBUG IS ON
UnNamedArgument:    "argument #1"
UnNamedOptionalArg: "second"
NamedFlag:          "my flag"

Vorlage.bat

@::!/dos/rocks
@echo off
goto :init

:header
    echo %__NAME% v%__VERSION%
    echo This is a sample batch file template,
    echo providing command-line arguments and flags.
    echo.
    goto :eof

:usage
    echo USAGE:
    echo   %__BAT_NAME% [flags] "required argument" "optional argument" 
    echo.
    echo.  /?, --help           shows this help
    echo.  /v, --version        shows the version
    echo.  /e, --verbose        shows detailed output
    echo.  -f, --flag value     specifies a named parameter value
    goto :eof

:version
    if "%~1"=="full" call :header & goto :eof
    echo %__VERSION%
    goto :eof

:missing_argument
    call :header
    call :usage
    echo.
    echo ****                                   ****
    echo ****    MISSING "REQUIRED ARGUMENT"    ****
    echo ****                                   ****
    echo.
    goto :eof

:init
    set "__NAME=%~n0"
    set "__VERSION=1.23"
    set "__YEAR=2017"

    set "__BAT_FILE=%~0"
    set "__BAT_PATH=%~dp0"
    set "__BAT_NAME=%~nx0"

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedOptionalArg="
    set "NamedFlag="

:parse
    if "%~1"=="" goto :validate

    if /i "%~1"=="/?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="-?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="--help"     call :header & call :usage "%~2" & goto :end

    if /i "%~1"=="/v"         call :version      & goto :end
    if /i "%~1"=="-v"         call :version      & goto :end
    if /i "%~1"=="--version"  call :version full & goto :end

    if /i "%~1"=="/e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="-e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="--verbose"  set "OptVerbose=yes"  & shift & goto :parse

    if /i "%~1"=="--flag"     set "NamedFlag=%~2"   & shift & shift & goto :parse
    if /i "%~1"=="-f"         set "NamedFlag=%~2"   & shift & shift & goto :parse

    if not defined UnNamedArgument     set "UnNamedArgument=%~1"     & shift & goto :parse
    if not defined UnNamedOptionalArg  set "UnNamedOptionalArg=%~1"  & shift & goto :parse

    shift
    goto :parse

:validate
    if not defined UnNamedArgument call :missing_argument & goto :end

:main
    if defined OptVerbose (
        echo **** DEBUG IS ON
    )

    echo UnNamedArgument:    "%UnNamedArgument%"

    if defined UnNamedOptionalArg      echo UnNamedOptionalArg: "%UnNamedOptionalArg%"
    if not defined UnNamedOptionalArg  echo UnNamedOptionalArg: not provided

    if defined NamedFlag               echo NamedFlag:          "%NamedFlag%"
    if not defined NamedFlag           echo NamedFlag:          not provided

:end
    call :cleanup
    exit /B

:cleanup
    REM The cleanup function is only really necessary if you
    REM are _not_ using SETLOCAL.
    set "__NAME="
    set "__VERSION="
    set "__YEAR="

    set "__BAT_FILE="
    set "__BAT_PATH="
    set "__BAT_NAME="

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedArgument2="
    set "NamedFlag="

    goto :eof

2 Stimmen

Was für ein Prachtexemplar! Für zukünftige Leser möchte ich nur hervorheben, dass die -f Flagge ist noch nicht in der Parse-Sektion enthalten. Nur eine Vorwarnung!

0 Stimmen

Ich habe deine Bearbeitung akzeptiert, @Flo. Danke!

1 Stimmen

Was bedeutet die erste Zeile, @::!/dos/rocks tun?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X