Jak przekazać parametry wiersza poleceń do pliku wsadowego?

Muszę przekazać id i hasło do pliku cmd (lub bat) w czasie uruchamiania, zamiast kodować je na twardo do pliku.

Oto jak wygląda linia poleceń:

test.cmd admin P@55w0rd > test-log.txt
Author: Peter Mortensen, 2008-08-25

15 answers

Kolejną użyteczną wskazówką jest użycie %*, aby oznaczać "wszystko". Na przykład:

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

Kiedy biegniesz:

test-command admin password foo bar

Powyższy plik wsadowy zostanie uruchomiony:

fake-command /u admin /p password foo bar

Może i źle zrozumiałam składnię, ale taka jest ogólna idea.

 836
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-04 16:54:25

Oto Jak to robię.

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

Oto jak wygląda linia poleceń:

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

%1 stosuje się do pierwszego parametru %2 (i tu jest najtrudniejsza część) stosuje się do drugiego. W ten sposób można przekazać do 9 parametrów.

 235
Author: Keng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-07 19:54:13

Jeśli chcesz inteligentnie obsłużyć brakujące parametry, możesz zrobić coś takiego:

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
 123
Author: thelsdj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 20:03:34

Dostęp do parametrów partii może być prosty za pomocą %1, %2, ... %9 lub również%*,
ale tylko wtedy, gdy treść jest prosta.

Nie ma prostego sposobu na złożoną zawartość, jak "&"^&, ponieważ nie można uzyskać dostępu do %1 bez wywołania błędu.

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

Linie rozszerzają się do

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

I każda linia zawiedzie, ponieważ jedna z & znajduje się poza cudzysłowem.

Można to rozwiązać odczytując z pliku tymczasowego wersję parametr.

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

Sztuczka polega na włączeniu echo on i rozwinięciu %1 po instrukcji rem (działa również z %2 .. %*).
Więc nawet "&"& może być odbity echem bez generowania błędu, jak to zauważono.

Ale aby móc przekierować wyjście echo on, potrzebujesz dwóch pętli for.

Dodatkowe znaki * # są używane do ochrony przed treściami takimi jak /? (pokazuje pomoc dla REM).
Lub karetka ^ na końcu linii może działać jako MULTILINIA znak, nawet po rem.

Następnie odczytanie parametru rem Z pliku, ale ostrożnie.
FOR / F powinien działać z opóźnionym rozszerzeniem off, w przeciwnym razie zawartość z "!"zostałby zniszczony.
Po usunięciu dodatkowych znaków w param1, masz to.

I aby używać param1 w bezpieczny sposób, włącz opóźnioną ekspansję.

 76
Author: jeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-09 14:02:58

Tak, i tylko nie zapomnij użyć zmiennych, takich jak %%1 podczas używania if i for i gangu.

Jeśli zapomnisz podwójnego %, wtedy podstawisz (ewentualnie null) argumenty linii poleceń i otrzymasz dość mylące komunikaty o błędach.

 53
Author: Frank Krueger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 18:16:32

Nie ma potrzeby tego komplikować. Jest to po prostu polecenie % 1% 2 parametry, na przykład

@echo off

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

echo copied %1 to %2

pause

"pauza" wyświetla, co zrobił plik wsadowy i czeka, aż naciśniesz dowolny klawisz. Zapisz to jako xx. bat w folderze Windows.

Aby go użyć, wpisz, na przykład:

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

Ten plik wsadowy dba o wszystkie niezbędne parametry, jak kopiowanie tylko plików, które są nowsze, itd. Używam go od czasów przed Windows. Jeśli lubisz oglądać nazwy plików, ponieważ są kopiowane, pomiń parametr Q.

 48
Author: DearWebby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-16 10:56:05
@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

Uwaga: Jeśli "%1"=="" spowoduje problemy, jeśli {[2] } jest zamknięta w cudzysłowach.

W takim przypadku użyj IF [%1]==[] lub, w NT 4 (SP6) i Później tylko, IF "%~1"=="".

 30
Author: rightcodeatrighttime,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-15 12:49:39

Znajomy pytał mnie ostatnio o ten temat, więc pomyślałem, że napiszę, jak radzę sobie z argumentami wiersza poleceń w plikach wsadowych.

Ta technika ma trochę na głowie, jak widać, ale sprawia, że moje pliki wsadowe są bardzo łatwe do zrozumienia i szybkie do wdrożenia. Jak również wspieranie następujących struktur:

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

The jist of it is having the :init, :parse, i :main funkcje.

Przykładowe użycie

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

Szablon.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
 23
Author: wasatchwizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-13 03:32:46

Niech to będzie proste.

Oto .plik cmd.

@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%

Oto 3 wywołania z linii poleceń.

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>
 18
Author: Love and peace - Joe Codeswell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-31 19:59:33
FOR %%A IN (%*) DO (
    REM Now your batch file handles %%A instead of %1
    REM No need to use SHIFT anymore.
    ECHO %%A
)

To pętla nad parametrami wsadowymi ( % * ) albo są one cytowane, albo nie, a następnie echo każdego parametru.

 16
Author: Amr Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 23:09:12

Napisałem prosty skrypt read_params, który może być wywołany jako funkcja (lub zewnętrzna .bat) i umieści wszystkie zmienne w bieżącym środowisku. Nie zmieni oryginalnych parametrów, ponieważ funkcja jest called z kopią oryginalnych parametrów.

Na przykład, biorąc pod uwagę następujące polecenie:

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

myscript.bat można by użyć zmiennych po wywołaniu funkcji:

call :read_params %*

echo %random%
echo %greeting%

Oto funkcja:

: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

Ograniczenia

  • nie można załadować argumentów bez wartości, takich jak -force. Możesz użyć -force=true, ale nie mogę wymyślić sposobu, aby zezwolić na puste wartości bez znajomości listy parametrów z wyprzedzeniem, które nie będą miały wartości.

Changelog

  • 2/18/2016
    • nie wymaga już opóźnionego rozszerzenia
    • działa teraz z innymi argumentami wiersza poleceń, szukając - przed parametrami.
 16
Author: Evan Kennedy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-18 22:29:05

Aby odnieść się do zmiennej ustawionej w wierszu poleceń, należy użyć " %a%", więc na przykład:

      set a=100 
      echo %a%  
      output = 100 

Uwaga: działa to w systemie Windows 7 pro.

 8
Author: CMS_95,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-02 15:20:43

Utwórz nowy plik wsadowy (przykład: openclass.bat) i zapisz tę linię w pliku:

java %~n1

Następnie umieść plik wsadowy w, powiedzmy, folderze system32, przejdź do pliku klasy Java, kliknij prawym przyciskiem myszy, Properties, Otwórz za pomocą... następnie znajdź swój plik wsadowy, wybierz go i to wszystko...

U mnie działa.

PS: nie mogę znaleźć sposobu na zamknięcie okna cmd, gdy zamykam klasę Java. Na razie...

 4
Author: SvenVP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-30 15:56:28

Proste rozwiązanie (choć pytanie jest stare)

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

Wyjście

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

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

YourLocalPath>pause
Press any key to continue . . .

Gdzie YourLocalPath jest bieżącą ścieżką katalogu.

Aby wszystko było proste, Zapisz polecenie param w zmiennej i użyj zmiennej do porównania.

Its not only simple to write but its simple to maintain as well so if later some other person or you read your script after long period of time, it will be easy to understand and utrzymać.

Aby napisać kod inline: zobacz inne odpowiedzi.

 2
Author: Amol Ramkrishna Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-03 13:48:36

Zainspirowany odpowiedzią gdzie indziej autorstwa @Jon, stworzyłem bardziej ogólny algorytm do wyodrębniania nazwanych parametrów, opcjonalnych wartości i przełączników.

Powiedzmy, że chcemy zaimplementować narzędzie foobar. Wymaga polecenia początkowego. Ma opcjonalny parametr --foo, który przyjmuje opcjonalną wartość (która oczywiście nie może być innym parametrem); jeśli brakuje wartości, domyślnie jest to default. Posiada również opcjonalny parametr --bar, który przyjmuje wymagane wartość. Na koniec może przyjąć flagę --baz bez dozwolonej wartości. A te parametry mogą być w dowolnej kolejności.

Innymi słowy, wygląda to tak:

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

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
  • użyj SETLOCAL, aby zmienne nie wydostały się do środowiska wywołującego.
  • nie zapomnij zainicjalizować zmiennych SET FOO=, itd. na wypadek, gdyby ktoś zdefiniował je w środowisku wywołującym.
  • użyj %~1, aby usunąć cytaty.
  • Użyj IF "%ARG%" == "", a nie IF [%ARG%] == [], ponieważ [ i ] w ogóle nie odtwarzaj woli z wartościami kończącymi się spacją.
  • nawet jeśli SHIFT znajduje się w bloku IF, bieżące args, takie jak %~1, nie są aktualizowane, ponieważ są ustalane podczas parsowania IF. Możesz użyć %~1 i %~2 wewnątrz bloku IF, ale byłoby to mylące, ponieważ masz SHIFT. Możesz umieścić SHIFT na końcu bloku dla jasności, ale to może się zgubić i / lub pomylić osób. Więc" przechwytywanie " %~1 i %~1 poza blokiem wydaje się najlepsze.
  • nie chcesz używać parametru zamiast opcjonalnej wartości innego parametru, więc musisz sprawdzić IF NOT "%ARG:~0,2%" == "--".
  • bądź ostrożny tylko SHIFT kiedy użyjesz jednego z parametrów.
  • zduplikowany kod SET FOO=%DEFAULT_FOO% jest godny pożałowania, ale alternatywą byłoby dodanie IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% poza blokiem IF NOT "%ARG%" == "". Jednak ponieważ jest on nadal wewnątrz IF "%PARAM%" == "--foo" bloku, wartość %FOO% będzie miała zostały ocenione i ustawione przed wejściem do bloku, aby nigdy nie wykryć, że zarówno parametr --foo był obecny , jak i że brakuje wartości %FOO%.
  • zauważ, że ECHO Missing bar value. 1>&2 wysyła komunikat o błędzie do stderr.
  • chcesz pustą linię w pliku wsadowym systemu Windows? Musisz użyć ECHO: lub jednej z odmian.
 1
Author: Garret Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-02 02:48:08