Hoe kan ik argumenten doorgeven aan een batchbestand?

Ik moet een ID en een wachtwoord doorgeven aan een batchbestand op het moment van het uitvoeren in plaats van hardcoding in het bestand.

Hier is wat de opdrachtregel eruit ziet:

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

1, Autoriteit 100%

Nog een nuttige tip is om %*te gebruiken om “ALL” te betekenen. Bijvoorbeeld:

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

Wanneer u uitvoert:

test-command admin password foo bar

Het bovenstaande batchbestand wordt uitgevoerd:

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

Ik heb de syntaxis enigszins verkeerd, maar dit is het algemene idee.


2, Autoriteit 29%

Hier is hoe ik het deed:

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

Hier is wat de opdracht eruit ziet:

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

De %1is van toepassing op de eerste parameter De %2(en hier is het lastige deel) van toepassing op de tweede. U kunt maximaal 9 parameters op deze manier hebben.


3, Autoriteit 14%

Als u een intelligente montage-parameters wilt omgaan, kunt u iets doen als:

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, Autoriteit 9%

Toegang tot batchparameters kan eenvoudig zijn met% 1,% 2, …% 9 of ook% *,
Maar alleen als de inhoud eenvoudig is.

Er is geen eenvoudige manier voor complexe inhoud zoals "&"^&, omdat het niet mogelijk is om% 1 te openen zonder een fout te maken.

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

De lijnen uitbreiden naar

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

en elke regel mislukt, als een van de &bevindt zich buiten de aanhalingstekens.

Het kan worden opgelost met het lezen van een tijdelijk bestand A Opmerkte versie van de parameter.

@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!'

De truc is om echo onin te schakelen en de% 1 uit te breiden na een remVerklaring (Werkt ook met %2 .. %*).
Dus zelfs "&"&kan worden echode zonder een fout te produceren, zoals deze wordt opgemerkt.

Maar om de uitvoer van de echo onte kunnen doorverwijzen, hebt u de twee for-lussen nodig.

De extra tekens * #worden gebruikt om veilig te zijn tegen de inhoud zoals /?(zou de hulp tonen voor rem).

Of een caret ^ aan het lijnkant kan werken als een multiline-personage, zelfs in na een rem.

Lees vervolgens de REM-parameter output uit het bestand, maar zorgvuldig.
De voor / f moet werken met vertraagde expansie uit, anders inhoud met “!” zou worden vernietigd.
Na het verwijderen van de extra tekens in param1, heb je het.

en om param1op een veilige manier te gebruiken, schakel de uitgestelde expansie in.


5, Autoriteit 5%

Het is niet nodig om het te bemoeilijken. Het is eenvoudigweg% 1% 2 parameters, bijvoorbeeld

@echo off
xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z
echo copied %1 to %2
pause

De “PAUSE” geeft weer wat het batchbestand heeft gedaan en wacht op u om de elke toets te raken. Sla dat op als xx.bat in de map Windows.

Typ bijvoorbeeld bijvoorbeeld:

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

Dit batchbestand zorgt voor alle nodige parameters, zoals alleen bestanden kopiëren, die nieuwer zijn, enz. Ik heb het sinds vóór Windows gebruikt. Als u het leuk vindt om de namen van de bestanden te zien, zoals ze worden gekopieerd, laat u de parameter Q.


6, Autoriteit 4%

Een vriend vroeg me onlangs over dit onderwerp, dus ik dacht dat ik zou plaatsen hoe ik opdrachtregelargumenten in batchbestanden omgaat.

Deze techniek heeft een beetje overhead als je zult zien, maar het maakt mijn batch-bestanden heel gemakkelijk te begrijpen en snel te implementeren. Evenals het ondersteunen van de volgende structuren:

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

De JIST van het heeft de :init, :parse, en :mainfuncties.

Voorbeeld gebruik

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

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

Antwoord 7, autoriteit 3%

In batchbestand

set argument1=%1
set argument2=%2
echo %argument1%
echo %argument2%

%1en %2retourneren respectievelijk de eerste en tweede argumentwaarden.

En geef in de opdrachtregel het argument door

Directory> batchFileName admin P@55w0rd 

Uitvoer zal zijn

admin
P@55w0rd

Antwoord 8, autoriteit 3%

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

Opmerking: IF "%1"==""zal problemen veroorzaken als %1zelf tussen aanhalingstekens staat.

Gebruik in dat geval IF [%1]==[]of, alleen in NT 4 (SP6) en later, IF "%~1"==""in plaats daarvan.


Antwoord 9, autoriteit 2%

Laten we het simpel houden.

Hier is het .cmd-bestand.

@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 zijn 3 oproepen vanaf de opdrachtregel.

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>

Antwoord 10, autoriteit 2%

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

Hiermee worden de batchparameters (%*) herhaald, al dan niet geciteerd, en wordt vervolgens elke parameter herhaald.


Antwoord 11, autoriteit 2%

Ik heb een eenvoudig read_params-script geschreven dat kan worden aangeroepen als een functie (of externe .bat) en alle variabelen in de huidige omgeving zal plaatsen. Het zal de originele parameters niet wijzigen omdat de functie wordt callmet een kopie van de originele parameters.

Bijvoorbeeld het volgende commando:

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

myscript.batzou de variabelen kunnen gebruiken na het aanroepen van de functie:

call :read_params %*
echo %random%
echo %greeting%

Dit is de functie:

: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

Beperkingen

  • Kan geen argumenten laden zonder waarde zoals -force. Je zou -force=truekunnen gebruiken, maar ik kan geen manier bedenken om lege waarden toe te staan zonder van tevoren een lijst met parameters te kennen die geen waarde hebben.

Wijzigingslogboek

  • 18-2-2016
    • Vereist geen vertraagde uitbreiding meer
    • Werkt nu met andere opdrachtregelargumenten door te zoeken naar -vóór parameters.

Antwoord 12

Om naar een ingestelde variabele in de opdrachtregel te verwijzen, moet u %a%gebruiken, dus bijvoorbeeld:

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

Opmerking: dit werkt voor Windows 7 pro.


Antwoord 13

Geïnspireerd door een antwoord eldersvan @Jon, heb ik een meer algemeen algoritme gemaakt voor het extraheren van benoemde parameters, optionele waarden , en schakelaars.

Laten we zeggen dat we een hulpprogramma foobarwillen implementeren. Het vereist een eerste opdracht. Het heeft een optionele parameter --foodie een optionelewaarde aanneemt (wat natuurlijk geen andere parameter kan zijn); als de waarde ontbreekt, wordt deze standaard ingesteld op default. Het heeft ook een optionele parameter --bardie een vereistewaarde aanneemt. Ten slotte kan het een vlag --bazhebben zonder toegestane waarde. Oh, en deze parameters kunnen in elke volgorde voorkomen.

Met andere woorden, het ziet er zo uit:

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

Hier is een oplossing:

@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
  • Gebruik SETLOCALzodat de variabelen niet ontsnappen naar de aanroepende omgeving.
  • Vergeet niet de variabelen SET FOO=, enz. te initialiseren voor het geval iemand ze in de oproepomgeving heeft gedefinieerd.
  • Gebruik %~1om aanhalingstekens te verwijderen.
  • Gebruik IF "%ARG%" == ""en niet IF [%ARG%] == []omdat [en ]speel helemaal geen will met waarden die eindigen op een spatie.
  • Zelfs als u SHIFTbinnen een IF-blok gebruikt, worden de huidige argumenten zoals %~1niet bijgewerkt omdat ze bepaald zijn wanneer de IFwordt geparseerd. Je zou %~1en %~2in het IF-blok kunnen gebruiken, maar het zou verwarrend zijn omdat je een SHIFT. Je zou voor de duidelijkheid de SHIFTaan het einde van het blok kunnen plaatsen, maar dat kan ook verloren gaan en/of mensen in verwarring brengen. Dus het “vangen” van %~1en %~1buiten het blok lijkt het beste.
  • U wilt geen parameter gebruiken in plaats van de optionele waarde van een andere parameter, dus u moet IF NOT "%ARG:~0,2%" == "--"aanvinken .
  • Wees voorzichtig met SHIFTwanneer u een van de parameters gebruikt.
  • De dubbele code SET FOO=%DEFAULT_FOO%is betreurenswaardig, maar het alternatief zou zijn om een ​​IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%Buiten de IF NOT "%ARG%" == ""BLOK. Omdat dit nog steeds in de IF "%PARAM%" == "--foo"blok, de %FOO%waarde zou zijn geëvalueerd en ingesteld voor u ooit Ingevoerde het blok, dus je zou nooit detecteren dat beide de --fooparameter aanwezig was en ook dat de %FOO%De waarde ontbrak.
  • Merk op dat ECHO Missing bar value. 1>&2Stuurt het foutbericht naar Stderr.
  • Wil je een lege regel in een Windows Batch-bestand? U moet ECHO:of een van de variaties.

14

Voor het gebruik van Looping Krijg alle argumenten en in Pure Batch:

OBS: voor het gebruik van zonder: ?*&|<>


@echo off && setlocal EnableDelayedExpansion
 for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && (
     call set "_arg_[!_cnt!]=!_arg_!" && for /l %%l in (!_cnt! 1 !_cnt!
     )do echo/ The argument n:%%l is: !_arg_[%%l]!
 )
goto :eof 

Uw code is klaar om iets te doen met het argumentnummer waar het nodig heeft, zoals …

@echo off && setlocal EnableDelayedExpansion
 for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!"
 fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt

Antwoord 15

Maak een nieuw batchbestand (voorbeeld: openclass.bat) en schrijf deze regel in het bestand:

java %~n1

Plaats vervolgens het batchbestand in, laten we zeggen, de system32-map, ga naar je Java-klassebestand, klik met de rechtermuisknop, Eigenschappen, Openen met…, zoek dan je batchbestand, selecteer het en dat is dat…

Het werkt voor mij.

PS: ik kan geen manier vinden om het cmd-venster te sluiten als ik de Java-klasse sluit. Voor nu…


Antwoord 16

Eenvoudige oplossing (ook al is de vraag oud)

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

uitvoer

YourLocalPath>call "C:\Temp\test.bat" pass123
YourLocalPath>echo off
"Batch started"
"arg1 is pass123"
YourLocalPath>pause
Press any key to continue . . .

Waar YourLocalPath het huidige mappad is.

Om de zaken eenvoudig te houden, slaat u de opdrachtparam op in variabele en gebruikt u variabele ter vergelijking.

Het is niet alleen eenvoudig te schrijven, maar ook eenvoudig te onderhouden, dus als iemand anders of u uw script later na lange tijd leest, is het gemakkelijk te begrijpen en te onderhouden.

Om code inline te schrijven: zie andere antwoorden.


Antwoord 17

Iedereen heeft geantwoord met zeer complexe antwoorden, maar het is eigenlijk heel eenvoudig. %1 %2 %3enzovoort worden de argumenten geparseerd naar het bestand. %1is argument 1, %2is argument 2 enzovoort.

Dus, als ik een bat-script heb dat dit bevat:

@echo off
echo %1

en wanneer ik het batchscript uitvoer, typ ik dit in:

C:> script.bat Hello

Het script wordt dit eenvoudig uitgevoerd:

Hello

Dit kan erg handig zijn voor bepaalde variabelen in een script, zoals een naam en leeftijd. Dus, als ik een script als volgt heb:

@echo off
echo Your name is: %1
echo Your age is: %2

Wanneer ik dit typ:

C:> script.bat Oliver 1000

Ik krijg de uitvoer hiervan:

Your name is: Oliver
Your age is: 1000

18

gepaarde argumenten

Als u de voorkeur geeft aan het passeren van de argumenten in een sleutelwaardepaar, kunt u iets dergelijks gebruiken:

@echo off
setlocal enableDelayedExpansion
:::::  asigning arguments as a key-value pairs:::::::::::::
set counter=0
for %%# in (%*) do (    
    set /a counter=counter+1
    set /a even=counter%%2
    if !even! == 0 (
        echo setting !prev! to %%#
        set "!prev!=%%~#"
    )
    set "prev=%%~#"
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: showing the assignments
echo %one% %two% %three% %four% %five%
endlocal

en een voorbeeld:

c:>argumentsDemo.bat one 1 "two" 2 three 3 four 4 "five" 5
1 2 3 4 5

Voorgedefinieerde variabelen

U kunt ook een aantal omgevingsvariabelen instellen. Het kan worden gedaan door ze in de console of :

@echo off
if defined variable1 (
    echo %variable1%
)
if defined variable2 (
    echo %variable2%
)

en het noemen als:

c:\>set variable1=1
c:\>set variable2=2
c:\>argumentsTest.bat
1
2

Bestand met vermelde waarden

U kunt ook naar een bestand verwijzen waarin de benodigde waarden vooraf zijn ingesteld.
Als dit het script is:

@echo off
setlocal
::::::::::
set "VALUES_FILE=E:\scripts\values.txt"
:::::::::::
for /f "usebackq eol=: tokens=* delims=" %%# in ("%VALUES_FILE%") do set "%%#"
echo %key1% %key2% %some_other_key%
endlocal

en waardenbestand is dit:

:::: use EOL=: in the FOR loop to use it as a comment
key1=value1
key2=value2
:::: do not left spaces arround the =
:::: or at the begining of the line
some_other_key=something else
and_one_more=more

de output van het aanroepen zal zijn:

waarde1 waarde2 iets anders

Natuurlijk kun je alle benaderingen combineren. Controleer ook argumentensyntaxis, shift

Other episodes