在Windows中,当运行批处理文件时如何访问传递的参数?
例如,假设我有一个名为hello.bat
的程序。当我在Windows命令行输入hello -a
时,我该如何让我的程序知道-a
已作为参数传递进来?
在Windows中,当运行批处理文件时如何访问传递的参数?
例如,假设我有一个名为hello.bat
的程序。当我在Windows命令行输入hello -a
时,我该如何让我的程序知道-a
已作为参数传递进来?
正如其他人已经说过的那样,通过命令行传递的参数可以在批处理文件中用符号%1
到%9
访问。还有两个其他的标记可供使用:
%0
是在命令行中指定的可执行文件(批处理文件)名称。%*
是在命令行中指定的所有参数——如果你想将这些参数转发给另一个程序,这非常有用。除了简单地访问这些参数之外,还有许多重要的技术需要注意。
这可以通过类似于IF "%~1"==""
的结构来完成,当且仅当根本没有传递任何参数时,它是真实的。请注意波浪线字符,它会导致删除值为%1
的任何周围引号;如果不带波浪线,则如果该值包含双引号,包括语法错误的可能性,则会得到意外的结果。
如果您需要访问超过9个参数,则必须使用命令SHIFT
。此命令将所有参数的值向左移一个位置,以便%0
获取%1
的值,%1
获取%2
的值,依此类推。如果存在第十个参数,则%9
获取其值,这在调用SHIFT
之前任何变量都无法访问(键入命令SHIFT /?
以获取更多选项)。
SHIFT
也很有用,当您想轻松处理参数而不需要按特定顺序呈现它们时。例如,脚本可能会识别任意顺序下的标志-a
和-b
。在这种情况下解析命令行的一个好方法是:
:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!
这个方案允许您解析非常复杂的命令行,而不会变得疯狂。
对于代表文件名的参数,shell 提供了许多与文件操作相关的功能,这些功能无法通过其他方式访问。这些功能使用以%~
开头的结构进行访问。
例如,要获取作为参数传递的文件的大小,请使用
ECHO %~z1
要获取批处理文件启动时所在目录的路径(非常有用!),可以使用
ECHO %~dp0
您可以在命令提示符中键入 CALL /?
来查看所有这些功能的完整范围。
"name=John"
这样的带引号的参数在执行期间会变成name John
。解决方法是用单引号括起来,'"name=John"'
。 - cmcgintyCALL /?
呢?!我一直在用 Google 瞎搞。 - bigtlb使用批处理文件中的参数:%0 和 %9
批处理文件可以使用令牌:%0
至 %9
,引用传递的单词作为参数。
%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.
%0
表示程序名称,如果在启动时运行AUTOEXEC.BAT文件,则%0
将为空。
示例:
在名为mybatch.bat
的批处理文件中输入以下命令:
@echo off
@echo hello %1 %2
pause
像这样调用批处理文件:mybatch john billy
将输出:
hello john billy
当批处理文件需要超过9个参数时,可以使用:%*
百分号星号标记%*
表示“剩余的参数”。 您可以使用for循环来获取它们,如此处所定义:
http://www.robvanderwoude.com/parameters.php
有关批处理参数分隔符的注意事项
命令行参数中的某些字符将被批处理文件忽略,这取决于DOS版本、它们是否被“转义”以及通常取决于它们在命令行中的位置:
commas (",") are replaced by spaces, unless they are part of a string in
double quotes
semicolons (";") are replaced by spaces, unless they are part of a string in
double quotes
"=" characters are sometimes replaced by spaces, not if they are part of a
string in double quotes
the first forward slash ("/") is replaced by a space only if it immediately
follows the command, without a leading space
multiple spaces are replaced by a single space, unless they are part of a
string in double quotes
tabs are replaced by a single space
leading spaces before the first command line argument are ignored
@Jon的:parse
/:endparse
方案是一个很好的开始,他的初步尝试让我非常感激,但如果你认为Windows那令人痛苦的批处理系统会这么轻易地放过你...哦,我的朋友,你会大吃一惊。我花了整整一天时间来应对这种恶魔般的问题,在经历了许多痛苦的研究和实验后,我最终成功地为一个真实的实用程序找到了一个可行的方法。
假设我们想要实现一个实用程序foobar
,它需要一个初始命令。它有一个可选参数--foo
,该参数接受一个可选值(当然不能是另一个参数);如果缺少该值,则默认为default
。它还有一个可选参数--bar
,该参数接受一个必填值。最后,它可以使用一个不允许带值的标志--baz
。噢,这些参数可以按任何顺序出现。
换句话说,它看起来像这样:
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
复杂?不,那似乎是真实生活公用事业的典型。(git
也是如此?)
话不多说,这里是一个解决方案:
@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
是的,情况确实很糟糕。请参见我在 https://dev59.com/xHVD5IYBdhLWcg3wTJrF#50653047 上发布的类似帖子,其中我提供了更多分析逻辑的内容,以及我为什么使用某些结构。
很恶心。我今天不得不学习大部分内容,感到很痛苦。
批处理文件会自动将程序后面的文本传递,只要有变量来分配它们。它们按发送顺序传递;例如,%1将是在调用程序后发送的第一个字符串等。
如果您有Hello.bat,并且内容如下:
@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause
如果您通过命令调用批处理程序,需要使用以下命令:
hello.bat APerson241 %date%
您将会收到以下回复:
Hello, APerson241 感谢您运行此批处理文件(01/11/2013)。
使用变量,即 .BAT
变量,并调用 %0
到 %9