Frage

Ich muss einer Batchdatei zum Zeitpunkt der Ausführung eine ID und ein Passwort übergeben, anstatt sie fest in die Datei zu codieren.

So sieht die Befehlszeile aus:

test.cmd admin P@55w0rd > test-log.txt
War es hilfreich?

Lösung 2

So habe ich es gemacht:

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

So sieht der Befehl aus:

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

Der %1 gilt für den ersten Parameter der %2 (und hier ist der knifflige Teil) gilt für den zweiten.Auf diese Weise können Sie bis zu 9 Parameter übergeben lassen.

Andere Tipps

Ein weiterer nützlicher Tipp ist die Verwendung %* „alle“ bedeuten.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

Die obige Batchdatei wird ausgeführt:

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

Möglicherweise ist die Syntax etwas falsch, aber das ist die allgemeine Idee.

Wenn Sie fehlende Parameter intelligent behandeln möchten, können Sie Folgendes 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

Der Zugriff auf Batch-Parameter kann einfach sein mit %1, %2, ...%9 oder auch %*,
aber nur, wenn der Inhalt einfach ist.

Es gibt keine einfache Möglichkeit 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 durch Lesen aus einer temporären Datei gelöst werden a 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, es zu aktivieren echo on und erweitern Sie %1 nach a rem Aussage (funktioniert auch mit %2 .. %*).
Also sogar "&"& könnte wiederholt werden, ohne einen Fehler zu erzeugen, wie bemerkt wird.

Aber um die Ausgabe des umleiten zu können echo on, benötigen Sie die beiden for-Schleifen.

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

Dann lesen Sie die rem-Parameter Ausgabe aus der Datei, aber sorgfältig.
Die für /f sollte mit einer verzögerten Expansion arbeiten, sonst Inhalt mit "!" würde zerstört werden.
Nach dem Entfernen der zusätzlichen Zeichen in param1, du hast es.

Und zu nutzen param1 ermöglichen Sie auf sichere Weise die verzögerte Erweiterung.

Ja, und vergessen Sie nicht, Variablen wie zu verwenden %%1 beim Benutzen if Und for und die Bande.

Wenn Sie das Double vergessen %, dann ersetzen Sie (möglicherweise null) Befehlszeilenargumente und erhalten einige ziemlich verwirrende Fehlermeldungen.

Es besteht kein Grund, es zu komplizieren.Es handelt sich einfach um den Befehl %1 %2 Parameter, zum Beispiel:

@echo off

xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z

echo copied %1 to %2

pause

Die „Pause“ zeigt an, was die Batchdatei getan hat, und wartet darauf, dass Sie die Taste ANY drücken.Speichern Sie das als xx.bat im Windows-Ordner.

Um es zu verwenden, geben Sie zum Beispiel Folgendes ein:

xx c:\f\30\*.* f:\sites\30

Diese Batchdatei kümmert sich um alle notwendigen Parameter, wie z. B. das Kopieren nur neuerer Dateien usw.Ich habe es schon vor Windows verwendet.Wenn Sie die Namen der Dateien beim Kopieren sehen möchten, lassen Sie das weg Q Parameter.

@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

Notiz:WENN "%1"=="" wird Probleme verursachen, wenn %1 wird selbst in Anführungszeichen gesetzt.

In diesem Fall verwenden Sie IF [%1]==[] oder, nur in NT 4 (SP6) und höher, IF "%~1"=="" stattdessen.

Ein Freund hat mich kürzlich zu diesem Thema gefragt, also dachte ich, ich poste mal, wie ich mit Befehlszeilenargumenten in Batchdateien umgehe.

Wie Sie sehen werden, verursacht diese Technik einen gewissen Mehraufwand, aber sie macht meine Batch-Dateien sehr einfach zu verstehen und schnell zu implementieren.Darüber hinaus unterstützen wir folgende Strukturen:

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

Das Wesentliche daran ist, das zu haben :init, :parse, Und :main Funktionen.

Beispielverwendung

>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"

template.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 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

Halten wir es einfach.

Hier ist die .cmd-Datei.

@echo off
rem this file is named echo_3params.cmd
echo %1
echo %2
echo %3
set v1=%1
set v2=%2
set v3=%3
echo v1 equals %v1%
echo v2 equals %v2%
echo v3 equals %v3%

Hier sind 3 Aufrufe von der Kommandozeile.

C:\Users\joeco>echo_3params 1abc 2 def  3 ghi
1abc
2
def
v1 equals 1abc
v2 equals 2
v3 equals def

C:\Users\joeco>echo_3params 1abc "2 def"  "3 ghi"
1abc
"2 def"
"3 ghi"
v1 equals 1abc
v2 equals "2 def"
v3 equals "3 ghi"

C:\Users\joeco>echo_3params 1abc '2 def'  "3 ghi"
1abc
'2
def'
v1 equals 1abc
v2 equals '2
v3 equals def'

C:\Users\joeco>
FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)

Dies durchläuft die Batch-Parameter (%*), unabhängig davon, ob sie in Anführungszeichen stehen oder nicht, und gibt dann jeden Parameter zurück.

Ich habe ein einfaches read_params-Skript geschrieben, das als Funktion (oder extern) aufgerufen werden kann .bat) und fügt alle Variablen in die aktuelle Umgebung ein.Die ursprünglichen Parameter werden nicht geändert, da die Funktion ausgeführt wird callmit einer Kopie der Originalparameter versehen.

Geben Sie beispielsweise den folgenden Befehl ein:

myscript.bat some -random=43 extra -greeting="hello world" fluff

myscript.bat könnte die Variablen nach dem Aufruf der Funktion verwenden:

call :read_params %*

echo %random%
echo %greeting%

Hier ist die Funktion:

:read_params
if not %1/==/ (
    if not "%__var%"=="" (
        if not "%__var:~0,1%"=="-" (
            endlocal
            goto read_params
        )
        endlocal & set %__var:~1%=%~1
    ) else (
        setlocal & set __var=%~1
    )
    shift
    goto read_params
)
exit /B

Einschränkungen

  • Argumente ohne Wert können nicht geladen werden, z. B -force.Du könntest benutzen -force=true Aber ich kann mir keine Möglichkeit vorstellen, leere Werte zuzulassen, ohne vorher eine Liste von Parametern zu kennen, die keinen Wert haben.

Änderungsprotokoll

  • 2/18/2016
    • Erfordert keine verzögerte Erweiterung mehr
    • Funktioniert jetzt mit anderen Befehlszeilenargumenten, indem nach gesucht wird - vor Parametern.

Um auf eine festgelegte Variable in der Befehlszeile zu verweisen, müssten Sie verwenden %a% also zum Beispiel:

set a=100 
echo %a%  
rem output = 100 

Notiz:Dies funktioniert für Windows 7 Pro.

Erstellen Sie eine neue Batchdatei (Beispiel:openclass.bat) und schreiben Sie diese Zeile in die Datei:

java %~n1

Platzieren Sie dann die Batch-Datei beispielsweise im Ordner system32, gehen Sie zu Ihrer Java-Klassendatei, klicken Sie mit der rechten Maustaste, Eigenschaften, Öffnen mit..., suchen Sie dann Ihre Batch-Datei, wählen Sie sie aus und fertig...

Für mich geht das.

PS:Ich kann keine Möglichkeit finden, das cmd-Fenster zu schließen, wenn ich die Java-Klasse schließe.Zur Zeit...

Inspiriert von einem woanders antworten von @Jon, ich habe einen allgemeineren Algorithmus zum Extrahieren benannter Parameter, optionaler Werte und Schalter erstellt.

Nehmen wir an, wir möchten ein Dienstprogramm implementieren foobar.Es erfordert einen ersten Befehl.Es verfügt über einen optionalen Parameter --foo Das dauert eine Optional Wert (der natürlich kein anderer Parameter sein kann);Wenn der Wert fehlt, wird standardmäßig verwendet default.Es gibt auch einen optionalen Parameter --bar Das dauert eine erforderlich Wert.Schließlich kann es eine Flagge vertragen --baz ohne zulässigen Wert.Oh, und diese Parameter können in beliebiger Reihenfolge vorliegen.

Mit anderen Worten sieht es so aus:

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

Hier ist 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
  • Verwenden SETLOCAL damit die Variablen nicht in die aufrufende Umgebung gelangen.
  • Vergessen Sie nicht, die Variablen zu initialisieren SET FOO=, usw.für den Fall, dass jemand sie in der aufrufenden Umgebung definiert hat.
  • Verwenden %~1 um Anführungszeichen zu entfernen.
  • Verwenden IF "%ARG%" == "" und nicht IF [%ARG%] == [] Weil [ Und ] Spielen Sie überhaupt nicht mit Werten, die mit einem Leerzeichen enden.
  • Auch wenn Du SHIFT innerhalb einer IF Block, die aktuellen Argumente wie z %~1 werden nicht aktualisiert, da sie bestimmt werden, wann die IF wird analysiert.Du könntest benutzen %~1 Und %~2 im Inneren IF Block, aber es wäre verwirrend, weil Sie einen hatten SHIFT.Du könntest das sagen SHIFT aus Gründen der Klarheit am Ende des Blocks, aber das könnte verloren gehen und/oder die Leute auch verwirren.Also „einfangen“ %~1 Und %~1 außerhalb des Blocks scheint am besten zu sein.
  • Sie möchten einen Parameter nicht anstelle des optionalen Werts eines anderen Parameters verwenden, also müssen Sie dies überprüfen IF NOT "%ARG:~0,2%" == "--".
  • Achten Sie nur darauf SHIFT wenn du verwenden einer der Parameter.
  • Der doppelte Code SET FOO=%DEFAULT_FOO% ist bedauerlich, aber die Alternative wäre, eine hinzuzufügen IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% außerhalb von IF NOT "%ARG%" == "" Block.Da sich dies jedoch immer noch im Inneren befindet IF "%PARAM%" == "--foo" Block, der %FOO% Der Wert wäre ausgewertet und festgelegt worden, bevor Sie den Block betreten hätten, sodass Sie das nie bemerken würden beide Die --foo Parameter vorhanden war und auch dass die %FOO% Wert fehlte.
  • Beachten Sie, dass ECHO Missing bar value. 1>&2 sendet die Fehlermeldung an stderr.
  • Möchten Sie eine Leerzeile in einer Windows-Batchdatei?Du musst es benutzen ECHO: oder eine der Variationen.

Einfache Lösung (auch wenn die Frage alt ist)

Test1.bat

echo off
echo "Batch started"
set arg1=%1
echo "arg1 is %arg1%"
echo on
pause

CallTest1.bat

call "C:\Temp\Test1.bat" pass123

Ausgabe

YourLocalPath>call "C:\Temp\test.bat" pass123

YourLocalPath>echo off
"Batch started"
"arg1 is pass123"

YourLocalPath>pause
Press any key to continue . . .

Wobei YourLocalPath der aktuelle Verzeichnispfad ist.

Um die Dinge einfach zu halten, speichern Sie den Befehlsparameter in einer Variablen und verwenden Sie die Variable zum Vergleich.

Es ist nicht nur einfach zu schreiben, sondern auch einfach zu warten. Wenn also später jemand anderes oder Sie Ihr Skript nach längerer Zeit lesen, ist es leicht zu verstehen und zu pflegen.

So schreiben Sie Code inline:siehe andere Antworten.

enter image description here

Um eine Schleife zu verwenden, erhalten Sie alle Argumente und im reinen Batch:

@echo off && setlocal EnableDelayedExpansion

 set "_cnt=0" && for %%Z in (%*) do ( 
 set "_arg_=%%Z" && set /a "_cnt=!_cnt! + 1" && set "_arg_[!_cnt!]=!_arg_!"
 shift && for /l %%l in (!_cnt! 1 !_cnt!) do echo/ The argument n:%%l is: !_arg_[%%l]!
 )

goto :eof 

Ihr Code ist bereit, mit der Argumentnummer dort etwas zu tun, wo er benötigt wird, z. B. ...

 @echo off && setlocal EnableDelayedExpansion

 set "_cnt=0" && for %%Z in (%*) do ( 
 set "_arg_=%%Z" && set /a "_cnt=!_cnt! + 1" && set "_arg_[!_cnt!]=!_arg_!"
 shift 

 )

 fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top