Как передать аргументы командному файлу?

Мне нужно передать идентификатор и пароль пакетному файлу во время его запуска, а не жестко закодировать их в файл.

Вот как выглядит командная строка:

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

По поводу «всего остального» см. Комментарий Грега Хегилла на как получить параметры командного файла с N-й позиции?

matt wilkie 08.01.2014 01:04

У меня есть сценарий запуска среды, который вставляет мое имя пользователя / пароль в переменные среды ... так что мне не нужно вводить их каждый раз ... Я использую bash большую часть времени (linux, mac и windows), и нужно использовать его для конфигов прокси в скриптах и ​​т. д. для работы.

Tracker1 07.10.2015 07:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1 223
2
1 997 869
18
Перейти к ответу Данный вопрос помечен как решенный

Ответы 18

Да, и просто не забывайте использовать такие переменные, как %%1, при использовании if, for и банды.

Если вы забудете двойной %, вы будете подставлять (возможно, нулевые) аргументы командной строки и получите довольно запутанные сообщения об ошибках.

%% только для if и for?

Royi Namir 27.10.2012 21:01

Хуже того - %% используется для префикса переменных и параметров командной строки внутри командных файлов. Но когда вы используете эти команды из командной строки, вы используете только% для префикса. Пример: внутри пакета: for %%d in (*) do echo %%d из командной строки: for %d in (*) do echo %d

Steve Midgley 16.01.2013 21:08

@SteveMidgley Я поддержал ваш комментарий примерно год назад. Затем я сразу забыл об этом, и как раз сегодня я пытался и смущенно смотрел на свой цикл for в командной строке и задавался вопросом, почему он пукнул и больше ничего не сделал. Итак, вот еще один виртуальный голос за меня. Я вернусь через год или около того, когда снова столкнусь с той же проблемой.

icc97 30.12.2016 00:53

Обычно мы резервируем цифры для обработки в командной строке, и, насколько мне известно, двойной процент применяется только к оператору for. @for %%2 in (testing) do @echo %%2 %1 в пакетном файле создает testing 1, когда он вызывается с 1 (test 1).

jwdonahue 22.01.2018 06:07

Ответ неверный. %%1 не имеет доступа к аргументу командной строки, и это также неверно для команды IF. Только команда FOR (в пакетных файлах) требует двойного процента, но даже тогда %%1 определит параметр FOR и не имеет доступа к аргументам.

jeb 03.03.2020 10:08

Еще один полезный совет - использовать %* для обозначения «все». Например:

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

Когда вы бежите:

test-command admin password foo bar

вышеуказанный командный файл будет запущен:

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

Я могу немного ошибиться в синтаксисе, но это общая идея.

% * фактически расширяется до всех параметров независимо от сдвига. Таким образом, даже после двух сдвигов у вас останутся первые два аргумента в% *. Вы можете использовать что-то вроде этого: stackoverflow.com/questions/761615/…, чтобы получить переменную, содержащую все, кроме первых n параметров.

Joey 02.05.2009 00:52

Обратите внимание, что% * работает не везде! Например, он не работает с DOSBox 0.73 (возможно, это ошибка, о которой следует сообщить).

Denilson Sá Maia 08.02.2010 05:50

Это не ошибка, потому что% * вообще никогда не работал в MS-DOS или Win9x.

Kef Schecter 23.11.2011 08:54

Я думаю, что shift «выталкивает» аргумент из списка. OP предположил, что %* будет выводить только оставшиеся аргументы, но это не работает, как сказал @Joey.

NathanAldenSr 08.06.2016 16:00

Это неверный ответ. Фактически это приводит к fake-command /u admin /p password admin password foo bar. На это много лет назад указал @Joey.

jwdonahue 22.01.2018 06:32

В данном случае две смены бессмысленны. ПОСЛЕ них% 1 станет foo, а% 2 станет bar, но это никоим образом не используется, и на% * не влияет команда shift.

Fotios Basagiannis 08.01.2019 13:03

Если вы хотите разумно обрабатывать отсутствующие параметры, вы можете сделать что-то вроде:

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

Какое значение имеют точка / точка в этих операциях равенства?

Chris 27.02.2017 18:22

Обычно, если% 1 пуст, это будет IF. ==. и так GOTO произойдет. Мы используем x здесь так: IF x% 1 == x -> IF x == x -> true

Carl 02.03.2017 17:48

Вы должны спросить, какова ценность «необоснованного аргумента»? Опять же, что вам следует проверить на «необоснованности аргументов»? Затем, если у вас нет ответа, вы должны использовать уловку, подобную одной из точек. Помните, что, как указано здесь, ss64.com/nt/if.html «Фактически вы можете использовать почти любой символ для этого '~' или фигурных скобок, {} или даже числа 4, но квадратные скобки, как правило, выбираются, потому что они не имеют особого значения. . "

Adriano G. V. Esposito 15.03.2018 16:39
Ответ принят как подходящий

Вот как я это сделал:

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

Вот как выглядит команда:

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

%1 применяется к первому параметру, %2 (и здесь есть хитрость) применяется ко второму. Таким образом можно передать до 9 параметров.

Если вы такой же тупой, как я, ваш ум искал echo %1 %2 и был отброшен простейшим случаем без вырезания и вставки с @ и fake-command с параметрами, думая, что мы получим содержимое fake-command.bat позже (в этом случае , слишком сложный fake-command.bat может иметь echo %2 %4, чтобы игнорировать имена параметров). Неправильно, тупица.TL; DR: Не будь таким тупым, как я. 1. echo echo %1 %2 > test.bat 2. test word1 word2. 3. Прибыль.

ruffin 05.03.2015 21:26

Пять лет спустя я снова читаю свой комментарий с недоумением. Похоже, это означало «создать .bat с двумя параметрами, буквально введите echo echo %1 %2 > test.bat. В файле test.bat будет echo %1 %2 (вы также могли бы сохранить его из текстового редактора). Теперь введите test word1 word2, чтобы вызвать и увидеть параметры работают. word1 word2 будет отображаться в командной строке. (echo %2 %4 проигнорировал бы /u и /p, поэтому вы могли бы вызвать test /u word1 /p word2, чтобы получить тот же результат). @ перед cmd в файле bat означает, что cmd не повторяется.

ruffin 01.08.2020 00:05

Создайте новый командный файл (пример: openclass.bat) и запишите в него эту строку:

java %~n1

Затем поместите командный файл, скажем, в папку system32, перейдите в свой файл класса Java, щелкните правой кнопкой мыши, выберите Свойства, Открыть с помощью ..., затем найдите свой командный файл, выберите его и все ...

Меня устраивает.

PS: Я не могу найти способ закрыть окно cmd, когда закрываю класс Java. Сейчас...

Вы можете закрыть окно cmd после закрытия процесса, используя следующую команду в пакетном сценарии: start /wait java %~n1

Paint_Ninja 31.07.2016 19:38

Советовать публике помещать случайные файлы сценариев в каталог system32 безответственно. Этот ответ действительно не затрагивает тему этой ветки.

jwdonahue 22.01.2018 06:24

Доступ к параметрам пакета может быть простым с помощью% 1,% 2, ...% 9 или также% *,
но только если содержание простое.

Нет простого способа для сложного содержимого, такого как "&"^&, поскольку невозможно получить доступ к% 1 без возникновения ошибки.

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

Линии расширяются до

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

И каждая строка выходит из строя, так как один из & находится вне кавычек.

Решить эту проблему можно чтением из временного файла версии параметра заметил.

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

Хитрость заключается в том, чтобы включить echo on и расширить% 1 после оператора rem (работает также с %2 .. %*) .
Таким образом, даже "&"& может быть воспроизведен без выдачи ошибки, как отмечается.

Но чтобы иметь возможность перенаправить вывод echo on, вам понадобятся два цикла for.

Дополнительные символы * # используются для защиты от содержимого вроде /? (будет отображаться справка для REM) .
Или курсор ^ в конце строки может работать как многострочный символ, даже после rem.

Затем прочтите вывод rem параметр из файла, но внимательно. FOR / F должен работать с отключенным отложенным расширением, иначе содержимое будет с "!" будет уничтожен.
После удаления лишних символов в param1 вы получили это.

А чтобы безопасно использовать param1, включите отложенное расширение.

for / F "tokens = *" %% a in ('echo% *') установить "all_args = %% a"

Kevin Edwards 11.04.2017 22:39

@KevinEdwards Тогда попробуйте с одним &, ваше решение работает только с простым контентом

jeb 11.04.2017 23:05

@KevinEdwards Я тестировал его, test.bat ^&, и он не работает. Работает только test.bat "&", но я не об этом. Вы не можете безопасно использовать %*, %1 без техники REM

jeb 13.04.2017 20:47

Ах, да, каретка не убегает от нее должным образом. Вам нужны цитаты, которые подходят для всех случаев использования, с которыми я сталкивался. Я просто хотел передать это. Спасибо за тестирование! Ваше здоровье :)

Kevin Edwards 15.04.2017 06:27

У меня есть опасения по поводу этого метода (трюк с echo-on-and-rem-piped-to-a-file): хотя пакет и cmd.exe не допускают символы новой строки в аргументах команд, но для оболочек, которые позволяют это при вызове скрипт, трюк перерывы. И не смейтесь, потому что PowerShell позволяет использовать символы новой строки в аргументах. Используя низкоуровневую функцию CreateProcess (), также можно создать новую строку и разбить ее.

Explorer09 25.04.2017 17:16

@ Explorer09 Batch, а также cmd.exe допускают оба символа новой строки в аргументах, но это сложно. echo-on-and-rem-redirect-to-a-file trick также может получать многострочные аргументы, но это не является доказательством пули, см. ТАК: ... многострочный текст в качестве аргумента ...

jeb 26.04.2017 01:15

@jeb Упомянутый вами ответ SO допускает синтаксический анализ многострочного аргумента, но не защищает от внедрения команды из строки 2 и далее. Я боюсь, что настоящего пуленепробиваемого решения не будет, пока не будет синтаксиса расширения (например, !1!!2! или !!1!!2), который действительно может задерживать-расширять аргументы.

Explorer09 26.04.2017 08:44

Слишком сложный и в основном не связанный напрямую с вопросом ОП.

jwdonahue 22.01.2018 04:15

@jwdonahue Да, это сложно (но не слишком сложно). Но особенно для паролей это может быть необходимо, по крайней мере, некоторые из моих паролей содержат амперсанды &, а также цитируют "

jeb 03.03.2020 10:11

Не нужно его усложнять. Это просто параметры команды% 1% 2, например,

@echo off

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

echo copied %1 to %2

pause

«Пауза» показывает, что сделал командный файл, и ждет, пока вы нажмете ЛЮБУЮ клавишу. Сохраните это как xx.bat в папке Windows.

Чтобы использовать его, введите, например:

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

Этот командный файл заботится обо всех необходимых параметрах, таких как копирование только новых файлов и т. д. Я использовал его еще до появления Windows. Если вам нравится видеть имена файлов при их копировании, не учитывайте параметр Q.

Чтобы обратиться к заданной переменной в командной строке, вам нужно будет использовать %a%, например:

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

Примечание: это работает для Windows 7 pro.

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

Примечание: ЕСЛИ "%1"= = "" вызовет проблемы, если сам %1 заключен в кавычки.

В этом случае используйте IF [%1]==[] или, только в NT 4 (SP6) и более поздних версиях, IF "%~1"= = "".

Достаточно верно, но это почти не касается предмета.

jwdonahue 22.01.2018 06:12

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

Это циклически перебирает параметры пакета (% *) независимо от того, указаны они или нет, а затем отображает каждый параметр.

Но терпит неудачу со многими разными аргументами, такими как test.bat *.txt, test.bat cat^&dog или Test.bat /?.

jeb 12.02.2020 15:31

Давайте будем простыми.

Вот файл .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%

Вот 3 вызова из командной строки.

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>

Я написал простой скрипт read_params, который можно вызвать как функцию (или внешний .bat), и он поместит все переменные в текущую среду. Он не изменит исходные параметры, потому что функция call дополняется копией исходных параметров.

Например, по следующей команде:

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

myscript.bat сможет использовать переменные после вызова функции:

call :read_params %*

echo %random%
echo %greeting%

Вот функция:

: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

Ограничения

  • Невозможно загрузить аргументы без значения, например -force. Вы можете использовать -force=true, но я не могу придумать способ разрешить пустые значения, не зная заранее список параметров, которые не будут иметь значения.

Журнал изменений

  • 18.02.2016
    • Больше не требует отложенного расширения
    • Теперь работает с другими аргументами командной строки, ища - перед параметрами.

Я смотрел на использование этого метода, так как я хотел бы передать аргументы в пакетный файл таким образом. Однако я заметил, что после того, как переменные установлены, даже после выхода из командного файла параметры все еще устанавливаются в cmd, если доступ к ним и пакет завершился, они не восстанавливаются в свое предыдущее состояние. Должен ли этот метод справиться с такой ситуацией?

Jono_2007 14.09.2016 14:53

По теме и лучше, чем некоторые другие ответы в этой ветке.

jwdonahue 22.01.2018 06:14

Расширен для поддержки аргументов флагов (без значений). Извините за отсутствие форматирования, но он не работает в комментариях: read_params if not% 1 / == / (если не "% __ var%" == "" (если не "% __ var: ~ 0,1%" == "-" (endlocal goto read_params) endlocal & set% __ var: ~ 1% =% ~ 1) else (setlocal & set __var =% ~ 1) shift goto read_params) else (если не "% __ var%" == "" (endlocal и установить% __ var: ~ 1% = 1))

Max 13.11.2019 22:26

Недавно друг спрашивал меня об этом, поэтому я подумал, что опубликую, как я обрабатываю аргументы командной строки в пакетных файлах.

Как вы увидите, этот метод имеет небольшие накладные расходы, но он делает мои командные файлы очень простыми для понимания и быстрой реализацией. А также поддерживая следующие конструкции:

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

В первую очередь это функции :init, :parse и :main.

Example usage

>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

Вдохновленный ответ в другом месте от @Jon, я создал более общий алгоритм для извлечения именованных параметров, необязательных значений и переключателей.

Допустим, мы хотим реализовать утилиту foobar. Требуется начальная команда. У него есть необязательный параметр --foo, который принимает значение необязательный (которое, конечно, не может быть другим параметром); если значение отсутствует, по умолчанию используется default. Он также имеет необязательный параметр --bar, который принимает значение требуется. Наконец, он может принимать флаг --baz без разрешенного значения. Да, и эти параметры могут быть в любом порядке.

Другими словами, это выглядит так:

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

Вот решение:

@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
  • Используйте SETLOCAL, чтобы переменные не попадали в вызывающую среду.
  • Не забудьте инициализировать переменные SET FOO= и т. д. На случай, если кто-то определил их в вызывающей среде.
  • Используйте %~1 для удаления кавычек.
  • Используйте IF "%ARG%" == "", а не IF [%ARG%] == [], потому что [ и ] вообще не воспроизводят волю со значениями, заканчивающимися пробелом.
  • Даже если вы используете SHIFT внутри блока IF, текущие аргументы, такие как %~1, не обновляются, потому что они определяются при анализе IF. Вы можете использовать %~1 и %~2 внутри блока IF, но это будет сбивать с толку, потому что у вас есть SHIFT. Вы можете поставить SHIFT в конце блока для ясности, но это также может потеряться и / или сбить с толку людей. Так что лучше всего выглядит «захват» %~1 и %~1 за пределами блока.
  • Вы не хотите использовать параметр вместо необязательного значения другого параметра, поэтому вам нужно проверить IF NOT "%ARG:~0,2%" == "--".
  • Будьте осторожны только с SHIFT, когда вы использовать один из параметров.
  • Дублирование кода SET FOO=%DEFAULT_FOO% прискорбно, но альтернативой было бы добавление IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% вне блока IF NOT "%ARG%" == "". Однако, поскольку он все еще находится внутри блока IF "%PARAM%" == "--foo", значение %FOO% было бы оценено и установлено до того, как вы когда-либо входили в блок, поэтому вы никогда не обнаружите, что обе параметр --foo присутствует а также, что значение %FOO% отсутствует.
  • Обратите внимание, что ECHO Missing bar value. 1>&2 отправляет сообщение об ошибке на stderr.
  • Хотите пустую строку в командном файле Windows? Вы должны использовать ECHO: или один из вариантов.

Простое решение (хотя вопрос старый)

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

выход

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

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

YourLocalPath>pause
Press any key to continue . . .

Где YourLocalPath - текущий путь к каталогу.

Для простоты сохраните параметр команды в переменной и используйте переменную для сравнения.

Его не только просто написать, но и легко поддерживать, поэтому, если позже кто-то другой или вы прочитаете ваш сценарий по прошествии длительного периода времени, его будет легко понять и поддерживать.

Чтобы написать встроенный код: см. Другие ответы.

For to use looping get all arguments and in pure batch:

Наблюдения: Для использования без: ?*&<>


@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 

Your code is ready to do something with the argument number where it needs, like...

 @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
 

В пакетном файле

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

%1 и %2 возвращают значения первого и второго аргументов соответственно.

И в командной строке передайте аргумент

Directory> batchFileName admin P@55w0rd 

Выход будет

admin
P@55w0rd

Парные аргументы

Если вы предпочитаете передавать аргументы в виде пары ключ-значение, вы можете использовать что-то вроде этого:

@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

И пример:

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

Предопределенные переменные

Вы также можете заранее установить некоторые переменные среды. Это можно сделать, установив их в консоли или установка их с моего компьютера:

@echo off

if defined variable1 (
    echo %variable1%
)

if defined variable2 (
    echo %variable2%
)

и назвав это так:

c:\>set variable1=1

c:\>set variable2=2

c:\>argumentsTest.bat
1
2

Файл с перечисленными значениями

Вы также можете указать файл, в котором предварительно установлены необходимые значения. Если это сценарий:

@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

и файл значений:

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

результат вызова будет:

value1 value2 something else

Конечно, можно комбинировать все подходы. Также проверьте синтаксис аргументов, сдвиг

Другие вопросы по теме