如何将命令行参数传递给批处理文件?

时间:2022-12-22 19:24:47

I need to pass id and password to a cmd (or bat) file at the time of running rather than hardcoding them into the file.

我需要在运行时将id和密码传递给cmd(或bat)文件,而不是将它们硬编码到文件中。

Here's what the command line looks like:

这是命令行的样子:

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

15 个解决方案

#1


855  

Another useful tip is to use %* to mean "all". For example:

另一个有用的提示是使用%*表示“全部”。例如:

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

When you run:

当你运行:

test-command admin password foo bar

the above batch file will run:

上面的批处理文件将运行:

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

I may have the syntax slightly wrong, but this is the general idea.

我的语法可能略有错误,但这是一般的想法。

#2


242  

Here's how I do it.

我就是这样做的。

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

Here's what the command line looks like:

这是命令行的样子:

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

The %1 applies to the first parameter the %2 (and here's the tricky part) applies to the second. You can have up to 9 parameters passed in this way.

%1适用于第一个参数%2(这里是棘手的部分)适用于第二个参数。您最多可以以这种方式传递9个参数。

#3


126  

If you want to intelligently handle missing parameters you can do something like:

如果您想要智能地处理缺失的参数,您可以执行以下操作:

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


79  

Accessing batch parameters can be simple with %1, %2, ... %9 or also %*,
but only if the content is simple.

使用%1,%2,...%9或%*来访问批处理参数可能很简单,但前提是内容很简单。

There is no simple way for complex contents like "&"^&, as it's not possible to access %1 without producing an error.

对于像“&”^&这样的复杂内容没有简单的方法,因为在不产生错误的情况下无法访问%1。

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

The lines expand to

线条扩展到

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

And each line fails, as one of the & is outside of the quotes.

并且每一行都失败了,因为其中一个&在引号之外。

It can be solved with reading from a temporary file a remarked version of the 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!'

The trick is to enable echo on and expand the %1 after a rem statement (works also with %2 .. %*).
So even "&"& could be echoed without producing an error, as it is remarked.

诀窍是在rem语句之后启用echo并扩展%1(也适用于%2 ..%*)。因此,即使是“&”&也可以在不产生错误的情况下得到回应。

But to be able to redirect the output of the echo on, you need the two for-loops.

但是为了能够重定向回声的输出,你需要两个for循环。

The extra characters * # are used to be safe against contents like /? (would show the help for REM).
Or a caret ^ at the line end could work as a multiline character, even in after a rem.

额外的字符*#用于对像/等内容安全吗? (会显示REM的帮助)。或者,行尾的插入符^可以作为多行字符,即使在rem之后也是如此。

Then reading the rem parameter output from the file, but carefully.
The FOR /F should work with delayed expansion off, else contents with "!" would be destroyed.
After removing the extra characters in param1, you got it.

然后从文件中读取rem参数输出,但要小心。 FOR / F应该使用延迟扩展,否则内容为“!”会被摧毁。删除param1中的多余字符后,就可以了。

And to use param1 in a safe way, enable the delayed expansion.

并以安全的方式使用param1,启用延迟扩展。

#5


53  

Yep, and just don't forget to use variables like %%1 when using if and for and the gang.

是的,当使用if和for和gang时,不要忘记使用%% 1之类的变量。

If you forget the double %, then you will be substituting in (possibly null) command line arguments and you will receive some pretty confusing error messages.

如果你忘记了double%,那么你将替换(可能为null)命令行参数,你会收到一些非常令人困惑的错误消息。

#6


48  

There is no need to complicate it. It is simply command %1 %2 parameters, for example,

没有必要使它复杂化。它只是命令%1%2参数,例如,

@echo off

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

echo copied %1 to %2

pause

The "pause" displays what the batch file has done and waits for you to hit the ANY key. Save that as xx.bat in the Windows folder.

“暂停”显示批处理文件已完成的操作,并等待您按下任意键。将其保存为Windows文件夹中的xx.bat。

To use it, type, for example:

要使用它,请键入,例如:

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

This batch file takes care of all the necessary parameters, like copying only files, that are newer, etc. I have used it since before Windows. If you like seeing the names of the files, as they are being copied, leave out the Q parameter.

这个批处理文件负责所有必要的参数,比如只复制文件,更新等等。我在Windows之前使用过它。如果您希望在复制文件时看到文件的名称,请忽略Q参数。

#7


30  

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

Note: IF "%1"=="" will cause problems if %1 is enclosed in quotes itself.

注意:如果%1包含在引号本身中,IF“%1”==“”将导致问题。

In that case, use IF [%1]==[] or, in NT 4 (SP6) and later only, IF "%~1"=="" instead.

在这种情况下,使用IF [%1] == []或者,在NT 4(SP6)和以后,仅使用IF“%〜1”==“”。

#8


25  

A friend was asking me about this subject recently, so I thought I'd post how I handle command-line arguments in batch files.

一位朋友最近问我这个问题,所以我想我会发布如何处理批处理文件中的命令行参数。

This technique has a bit of overhead as you'll see, but it makes my batch files very easy to understand and quick to implement. As well as supporting the following structures:

正如您所看到的,这种技术有一些开销,但它使我的批处理文件非常易于理解和快速实现。除了支持以下结构:

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

The jist of it is having the :init, :parse, and :main functions.

它的主旨是: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

#9


18  

Let's keep this simple.

让我们保持这个简单。

Here is the .cmd file.

这是.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%

Here are 3 calls from the command line.

这是来自命令行的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>

#10


17  

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

This loops over the batch parameters (%*) either they are quoted or not, then echos each parameter.

这将循环播放批处理参数(%*),或者引用它们,然后回显每个参数。

#11


16  

I wrote a simple read_params script that can be called as a function (or external .bat) and will put all variables into the current environment. It won't modify the original parameters because the function is being called with a copy of the original parameters.

我写了一个简单的read_params脚本,可以作为函数(或外部.bat)调用,并将所有变量放入当前环境。它不会修改原始参数,因为正在使用原始参数的副本调用函数。

For example, given the following command:

例如,给定以下命令:

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

myscript.bat would be able to use the variables after calling the function:

myscript.bat可以在调用函数后使用变量:

call :read_params %*

echo %random%
echo %greeting%

Here's the function:

这是功能:

: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

Limitations

  • Cannot load arguments with no value such as -force. You could use -force=true but I can't think of a way to allow blank values without knowing a list of parameters ahead of time that won't have a value.
  • 无法加载没有值的参数,例如-force。你可以使用-force = true但是我想不出一种方法来允许空白值而不知道提前没有值的参数列表。


Changelog

  • 2/18/2016
    • No longer requires delayed expansion
    • 不再需要延迟扩张

    • Now works with other command line arguments by looking for - before parameters.
    • 现在通过查找 - before参数来使用其他命令行参数。

  • 2/18/2016不再需要延迟扩展现在通过查找 - 在参数之前使用其他命令行参数。

#12


8  

To refer to a set variable in command line you would need to use " %a% " so for example:

要在命令行中引用set变量,您需要使用“%a%”,例如:

      set a=100 
      echo %a%  
      output = 100 

Note: This works for Windows 7 pro.

注意:这适用于Windows 7专业版。

#13


4  

Make a new batch file (example: openclass.bat) and write this line in the file:

创建一个新的批处理文件(例如:openclass.bat)并在文件中写入以下行:

java %~n1

Then place the batch file in, let's say, the system32 folder, go to your Java class file, right click, Properties, Open with..., then find your batch file, select it and that's that...

然后将批处理文件放在system32文件夹中,转到Java类文件,右键单击,属性,打开...,然后找到批处理文件,选择它,那就是...

It works for me.

这个对我有用。

PS: I can't find a way to close the cmd window when I close the Java class. For now...

PS:关闭Java类时,我无法找到关闭cmd窗口的方法。目前...

#14


3  

Inspired by an answer elsewhere by @Jon, I have crafted a more general algorithm for extracting named parameters, optional values, and switches.

受到@Jon其他地方的答案的启发,我制作了一个更通用的算法来提取命名参数,可选值和开关。

Let us say that we want to implement a utility foobar. It requires an initial command. It has an optional parameter --foo which takes an optional value (which cannot be another parameter, of course); if the value is missing it defaults to default. It also has an optional parameter --bar which takes a required value. Lastly it can take a flag --baz with no value allowed. Oh, and these parameters can come in any order.

让我们说我们想要实现一个实用程序foobar。它需要一个初始命令。它有一个可选参数--foo,它带有一个可选值(当然不能是另一个参数);如果该值丢失,则默认为默认值。它还有一个可选参数--bar,它带有一个必需的值。最后它可以带一个标志--baz没有允许值。哦,这些参数可以按任何顺序排列。

In other words, it looks like this:

换句话说,它看起来像这样:

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

Here is a solution:

这是一个解决方案:

@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
  • Use SETLOCAL so that the variables don't escape into the calling environment.
  • 使用SETLOCAL,以便变量不会转义到调用环境中。

  • Don't forget to initialize the variables SET FOO=, etc. in case someone defined them in the calling environment.
  • 如果有人在调用环境中定义变量,请不要忘记初始化变量SET FOO =等。

  • Use %~1 to remove quotes.
  • 使用%~1删除引号。

  • Use IF "%ARG%" == "" and not IF [%ARG%] == [] because [ and ] don't play will at all with values ending in a space.
  • 使用IF“%ARG%”==“”而不是IF [%ARG%] == [],因为[和]不会播放以空格结尾的值。

  • Even if you SHIFT inside an IF block, the current args such as %~1 don't get updated because they are determined when the IF is parsed. You could use %~1 and %~2 inside the IF block, but it would be confusing because you had a SHIFT. You could put the SHIFT at the end of the block for clarity, but that might get lost and/or confuse people as well. So "capturing" %~1 and %~1 outside the block seems best.
  • 即使您在IF块内部进行SHIFT,当前的参数(例如%~1)也不会更新,因为它们是在解析IF时确定的。你可以在IF块中使用%~1和%~2,但是因为你有一个SHIFT会让人感到困惑。为了清楚起见,您可以将SHIFT放在块的末尾,但这可能会丢失和/或混淆人们。因此,在块外“捕获”%~1和%~1似乎是最好的。

  • You don't want to use a parameter in place of another parameter's optional value, so you have to check IF NOT "%ARG:~0,2%" == "--".
  • 您不希望使用参数代替其他参数的可选值,因此您必须检查IF NOT“%ARG:~0,2%”==“ - ”。

  • Be careful only to SHIFT when you use one of the parameters.
  • 使用其中一个参数时,请注意SHIFT。

  • The duplicate code SET FOO=%DEFAULT_FOO% is regrettable, but the alternative would be to add an IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% outside the IF NOT "%ARG%" == "" block. However because this is still inside the IF "%PARAM%" == "--foo" block, the %FOO% value would have been evaluated and set before you ever entered the block, so you would never detect that both the --foo parameter was present and also that the %FOO% value was missing.
  • 重复代码SET FOO =%DEFAULT_FOO%是令人遗憾的,但替代方案是在IF NOT“%ARG%”==“”块之外添加IF“%FOO%”==“”SET FOO =%DEFAULT_FOO% 。但是因为它仍在IF“%PARAM%”==“ - foo”块中,所以%FOO%值将在您进入块之前进行评估和设置,因此您永远不会检测到 - foo参数存在,并且还缺少%FOO%值。

  • Note that ECHO Missing bar value. 1>&2 sends the error message to stderr.
  • 注意ECHO缺少条形值。 1>&2将错误消息发送给stderr。

  • Want a blank line in a Windows batch file? You gotta use ECHO: or one of the variations.
  • 想要Windows批处理文件中的空白行?你必须使用ECHO:或其中一个变种。

#15


2  

Simple solution(even though question is old)

简单的解决方案(即使问题很旧)

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

output

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

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

YourLocalPath>pause
Press any key to continue . . .

Where YourLocalPath is current directory path.

WhereLocalPath是当前目录路径。

To keep things simple store the command param in variable and use variable for comparison.

为了简单起见,将命令参数存储在变量中并使用变量进行比较。

Its not just 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 maintain.

它不仅易于编写,而且易于维护,因此如果以后其他人或您在很长一段时间后阅读您的脚本,它将很容易理解和维护。

To write code inline : see other answers.

编写内联代码:请参阅其他答案。

#1


855  

Another useful tip is to use %* to mean "all". For example:

另一个有用的提示是使用%*表示“全部”。例如:

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

When you run:

当你运行:

test-command admin password foo bar

the above batch file will run:

上面的批处理文件将运行:

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

I may have the syntax slightly wrong, but this is the general idea.

我的语法可能略有错误,但这是一般的想法。

#2


242  

Here's how I do it.

我就是这样做的。

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

Here's what the command line looks like:

这是命令行的样子:

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

The %1 applies to the first parameter the %2 (and here's the tricky part) applies to the second. You can have up to 9 parameters passed in this way.

%1适用于第一个参数%2(这里是棘手的部分)适用于第二个参数。您最多可以以这种方式传递9个参数。

#3


126  

If you want to intelligently handle missing parameters you can do something like:

如果您想要智能地处理缺失的参数,您可以执行以下操作:

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


79  

Accessing batch parameters can be simple with %1, %2, ... %9 or also %*,
but only if the content is simple.

使用%1,%2,...%9或%*来访问批处理参数可能很简单,但前提是内容很简单。

There is no simple way for complex contents like "&"^&, as it's not possible to access %1 without producing an error.

对于像“&”^&这样的复杂内容没有简单的方法,因为在不产生错误的情况下无法访问%1。

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

The lines expand to

线条扩展到

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

And each line fails, as one of the & is outside of the quotes.

并且每一行都失败了,因为其中一个&在引号之外。

It can be solved with reading from a temporary file a remarked version of the 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!'

The trick is to enable echo on and expand the %1 after a rem statement (works also with %2 .. %*).
So even "&"& could be echoed without producing an error, as it is remarked.

诀窍是在rem语句之后启用echo并扩展%1(也适用于%2 ..%*)。因此,即使是“&”&也可以在不产生错误的情况下得到回应。

But to be able to redirect the output of the echo on, you need the two for-loops.

但是为了能够重定向回声的输出,你需要两个for循环。

The extra characters * # are used to be safe against contents like /? (would show the help for REM).
Or a caret ^ at the line end could work as a multiline character, even in after a rem.

额外的字符*#用于对像/等内容安全吗? (会显示REM的帮助)。或者,行尾的插入符^可以作为多行字符,即使在rem之后也是如此。

Then reading the rem parameter output from the file, but carefully.
The FOR /F should work with delayed expansion off, else contents with "!" would be destroyed.
After removing the extra characters in param1, you got it.

然后从文件中读取rem参数输出,但要小心。 FOR / F应该使用延迟扩展,否则内容为“!”会被摧毁。删除param1中的多余字符后,就可以了。

And to use param1 in a safe way, enable the delayed expansion.

并以安全的方式使用param1,启用延迟扩展。

#5


53  

Yep, and just don't forget to use variables like %%1 when using if and for and the gang.

是的,当使用if和for和gang时,不要忘记使用%% 1之类的变量。

If you forget the double %, then you will be substituting in (possibly null) command line arguments and you will receive some pretty confusing error messages.

如果你忘记了double%,那么你将替换(可能为null)命令行参数,你会收到一些非常令人困惑的错误消息。

#6


48  

There is no need to complicate it. It is simply command %1 %2 parameters, for example,

没有必要使它复杂化。它只是命令%1%2参数,例如,

@echo off

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

echo copied %1 to %2

pause

The "pause" displays what the batch file has done and waits for you to hit the ANY key. Save that as xx.bat in the Windows folder.

“暂停”显示批处理文件已完成的操作,并等待您按下任意键。将其保存为Windows文件夹中的xx.bat。

To use it, type, for example:

要使用它,请键入,例如:

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

This batch file takes care of all the necessary parameters, like copying only files, that are newer, etc. I have used it since before Windows. If you like seeing the names of the files, as they are being copied, leave out the Q parameter.

这个批处理文件负责所有必要的参数,比如只复制文件,更新等等。我在Windows之前使用过它。如果您希望在复制文件时看到文件的名称,请忽略Q参数。

#7


30  

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

Note: IF "%1"=="" will cause problems if %1 is enclosed in quotes itself.

注意:如果%1包含在引号本身中,IF“%1”==“”将导致问题。

In that case, use IF [%1]==[] or, in NT 4 (SP6) and later only, IF "%~1"=="" instead.

在这种情况下,使用IF [%1] == []或者,在NT 4(SP6)和以后,仅使用IF“%〜1”==“”。

#8


25  

A friend was asking me about this subject recently, so I thought I'd post how I handle command-line arguments in batch files.

一位朋友最近问我这个问题,所以我想我会发布如何处理批处理文件中的命令行参数。

This technique has a bit of overhead as you'll see, but it makes my batch files very easy to understand and quick to implement. As well as supporting the following structures:

正如您所看到的,这种技术有一些开销,但它使我的批处理文件非常易于理解和快速实现。除了支持以下结构:

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

The jist of it is having the :init, :parse, and :main functions.

它的主旨是: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

#9


18  

Let's keep this simple.

让我们保持这个简单。

Here is the .cmd file.

这是.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%

Here are 3 calls from the command line.

这是来自命令行的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>

#10


17  

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

This loops over the batch parameters (%*) either they are quoted or not, then echos each parameter.

这将循环播放批处理参数(%*),或者引用它们,然后回显每个参数。

#11


16  

I wrote a simple read_params script that can be called as a function (or external .bat) and will put all variables into the current environment. It won't modify the original parameters because the function is being called with a copy of the original parameters.

我写了一个简单的read_params脚本,可以作为函数(或外部.bat)调用,并将所有变量放入当前环境。它不会修改原始参数,因为正在使用原始参数的副本调用函数。

For example, given the following command:

例如,给定以下命令:

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

myscript.bat would be able to use the variables after calling the function:

myscript.bat可以在调用函数后使用变量:

call :read_params %*

echo %random%
echo %greeting%

Here's the function:

这是功能:

: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

Limitations

  • Cannot load arguments with no value such as -force. You could use -force=true but I can't think of a way to allow blank values without knowing a list of parameters ahead of time that won't have a value.
  • 无法加载没有值的参数,例如-force。你可以使用-force = true但是我想不出一种方法来允许空白值而不知道提前没有值的参数列表。


Changelog

  • 2/18/2016
    • No longer requires delayed expansion
    • 不再需要延迟扩张

    • Now works with other command line arguments by looking for - before parameters.
    • 现在通过查找 - before参数来使用其他命令行参数。

  • 2/18/2016不再需要延迟扩展现在通过查找 - 在参数之前使用其他命令行参数。

#12


8  

To refer to a set variable in command line you would need to use " %a% " so for example:

要在命令行中引用set变量,您需要使用“%a%”,例如:

      set a=100 
      echo %a%  
      output = 100 

Note: This works for Windows 7 pro.

注意:这适用于Windows 7专业版。

#13


4  

Make a new batch file (example: openclass.bat) and write this line in the file:

创建一个新的批处理文件(例如:openclass.bat)并在文件中写入以下行:

java %~n1

Then place the batch file in, let's say, the system32 folder, go to your Java class file, right click, Properties, Open with..., then find your batch file, select it and that's that...

然后将批处理文件放在system32文件夹中,转到Java类文件,右键单击,属性,打开...,然后找到批处理文件,选择它,那就是...

It works for me.

这个对我有用。

PS: I can't find a way to close the cmd window when I close the Java class. For now...

PS:关闭Java类时,我无法找到关闭cmd窗口的方法。目前...

#14


3  

Inspired by an answer elsewhere by @Jon, I have crafted a more general algorithm for extracting named parameters, optional values, and switches.

受到@Jon其他地方的答案的启发,我制作了一个更通用的算法来提取命名参数,可选值和开关。

Let us say that we want to implement a utility foobar. It requires an initial command. It has an optional parameter --foo which takes an optional value (which cannot be another parameter, of course); if the value is missing it defaults to default. It also has an optional parameter --bar which takes a required value. Lastly it can take a flag --baz with no value allowed. Oh, and these parameters can come in any order.

让我们说我们想要实现一个实用程序foobar。它需要一个初始命令。它有一个可选参数--foo,它带有一个可选值(当然不能是另一个参数);如果该值丢失,则默认为默认值。它还有一个可选参数--bar,它带有一个必需的值。最后它可以带一个标志--baz没有允许值。哦,这些参数可以按任何顺序排列。

In other words, it looks like this:

换句话说,它看起来像这样:

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

Here is a solution:

这是一个解决方案:

@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
  • Use SETLOCAL so that the variables don't escape into the calling environment.
  • 使用SETLOCAL,以便变量不会转义到调用环境中。

  • Don't forget to initialize the variables SET FOO=, etc. in case someone defined them in the calling environment.
  • 如果有人在调用环境中定义变量,请不要忘记初始化变量SET FOO =等。

  • Use %~1 to remove quotes.
  • 使用%~1删除引号。

  • Use IF "%ARG%" == "" and not IF [%ARG%] == [] because [ and ] don't play will at all with values ending in a space.
  • 使用IF“%ARG%”==“”而不是IF [%ARG%] == [],因为[和]不会播放以空格结尾的值。

  • Even if you SHIFT inside an IF block, the current args such as %~1 don't get updated because they are determined when the IF is parsed. You could use %~1 and %~2 inside the IF block, but it would be confusing because you had a SHIFT. You could put the SHIFT at the end of the block for clarity, but that might get lost and/or confuse people as well. So "capturing" %~1 and %~1 outside the block seems best.
  • 即使您在IF块内部进行SHIFT,当前的参数(例如%~1)也不会更新,因为它们是在解析IF时确定的。你可以在IF块中使用%~1和%~2,但是因为你有一个SHIFT会让人感到困惑。为了清楚起见,您可以将SHIFT放在块的末尾,但这可能会丢失和/或混淆人们。因此,在块外“捕获”%~1和%~1似乎是最好的。

  • You don't want to use a parameter in place of another parameter's optional value, so you have to check IF NOT "%ARG:~0,2%" == "--".
  • 您不希望使用参数代替其他参数的可选值,因此您必须检查IF NOT“%ARG:~0,2%”==“ - ”。

  • Be careful only to SHIFT when you use one of the parameters.
  • 使用其中一个参数时,请注意SHIFT。

  • The duplicate code SET FOO=%DEFAULT_FOO% is regrettable, but the alternative would be to add an IF "%FOO%" == "" SET FOO=%DEFAULT_FOO% outside the IF NOT "%ARG%" == "" block. However because this is still inside the IF "%PARAM%" == "--foo" block, the %FOO% value would have been evaluated and set before you ever entered the block, so you would never detect that both the --foo parameter was present and also that the %FOO% value was missing.
  • 重复代码SET FOO =%DEFAULT_FOO%是令人遗憾的,但替代方案是在IF NOT“%ARG%”==“”块之外添加IF“%FOO%”==“”SET FOO =%DEFAULT_FOO% 。但是因为它仍在IF“%PARAM%”==“ - foo”块中,所以%FOO%值将在您进入块之前进行评估和设置,因此您永远不会检测到 - foo参数存在,并且还缺少%FOO%值。

  • Note that ECHO Missing bar value. 1>&2 sends the error message to stderr.
  • 注意ECHO缺少条形值。 1>&2将错误消息发送给stderr。

  • Want a blank line in a Windows batch file? You gotta use ECHO: or one of the variations.
  • 想要Windows批处理文件中的空白行?你必须使用ECHO:或其中一个变种。

#15


2  

Simple solution(even though question is old)

简单的解决方案(即使问题很旧)

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

output

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

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

YourLocalPath>pause
Press any key to continue . . .

Where YourLocalPath is current directory path.

WhereLocalPath是当前目录路径。

To keep things simple store the command param in variable and use variable for comparison.

为了简单起见,将命令参数存储在变量中并使用变量进行比较。

Its not just 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 maintain.

它不仅易于编写,而且易于维护,因此如果以后其他人或您在很长一段时间后阅读您的脚本,它将很容易理解和维护。

To write code inline : see other answers.

编写内联代码:请参阅其他答案。