当您希望轻松处理参数而不要求它们按特定顺序显示时, 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!
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
@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
5 回答
正如其他人已经说过的那样,通过命令行传递的参数可以使用符号
%1
到%9
在批处理文件中访问 . 您还可以使用另外两个令牌:%0
是 the executable (batch file) name as specified in the command line .%*
是 all parameters specified in the command line - 如果要将参数转发到另一个程序,这非常有用 .除了如何访问参数之外,还有许多重要的技术需要注意 .
检查参数是否已通过
这是通过
IF "%~1"==""
之类的结构完成的,当且仅当根本没有传递任何参数时才是真的 . 请注意,波形符字符会导致从%1
的值中删除任何周围的引号;如果该值包含双引号,则包括语法错误的可能性,如果没有波形符,您将获得意外结果 .处理超过9个参数(或者只是让生活更轻松)
如果需要访问9个以上的参数,则必须使用命令
SHIFT
. 此命令将所有参数的值移动一个位置,以便%0
取值%1
,%1
取值%2
等.%9
取第十个参数的值(如果存在),这是不可通过任何参数调用SHIFT
之前的变量(输入命令SHIFT /?
以获取更多选项) .当您希望轻松处理参数而不要求它们按特定顺序显示时,
SHIFT
也很有用 . 例如,脚本可以按任何顺序识别标志-a
和-b
. 在这种情况下解析命令行的好方法是此方案允许您解析相当复杂的命令行而不会疯狂 .
替换批处理参数
对于表示文件名的参数,shell提供了许多与处理无法以任何其他方式访问的文件相关的功能 . 使用以
%~
开头的结构访问此功能 .例如,要获取作为参数使用传入的文件的大小
要获取启动批处理文件的目录的路径(非常有用!),您可以使用
您可以通过在命令提示符下键入
CALL /?
来查看所有这些功能 .Using parameters in batch files: %0 and %9
批处理文件可以引用作为参数传入的单词以及令牌:
%0
到%9
.在命令行上传入的参数必须是字母数字字符并用空格分隔 . 由于
%0
是调用的程序名,因此在DOS中%0
对于AUTOEXEC.BAT将为空,如果在启动时启动的话 .Example:
将以下命令放在名为
mybatch.bat
的批处理文件中:像这样调用批处理文件:
mybatch john billy
将输出:Get more than 9 parameters for a batch file, use: %*
百分之星号令牌
%*
表示"the rest of the parameters" . 您可以使用for循环来抓取它们,如下所示:http://www.robvanderwoude.com/parameters.php
Notes about delimiters for batch parameters
批处理文件中的某些字符会被批处理文件忽略,具体取决于DOS版本,是否“转义”,并且通常取决于它们在命令行中的位置:
批处理文件会自动在程序之后传递文本,只要它们是要分配给它们的变量即可 . 它们被传递以便发送;例如%1将是调用程序后发送的第一个字符串,等等 .
如果你有Hello.bat,内容是:
并通过命令调用批处理
你应该收到这封邮件:
您好,APerson241感谢您运行此批处理文件(01/11/2013)
使用变量,即
.BAT
变量,并调用%0
至%9
@ Jon的
:parse
/:endparse
计划是一个很好的开始,他对最初的通行证表示感谢,但是如果你认为Windows那种痛苦的批处理系统会让你轻易放弃......好吧,我的朋友,你很震惊 . 我花了整整一天的时间与这个恶魔一起度过,经过多次痛苦的研究和实验,我终于为一个真实的实用工具做了一些可行的工作 .我们假设我们要实现一个实用程序
foobar
. 它需要一个初始命令 . 它有一个可选参数--foo
,它带有一个可选值(当然不能是另一个参数);如果值丢失,则默认为default
. 它还有一个可选参数--bar
,它取一个必需的值 . 最后,它可以带一个标志--baz
,不允许任何值 . 哦,这些参数可以按任何顺序排列 .换句话说,它看起来像这样:
复杂?不,这似乎是现实生活中很常见的 . (
git
任何人?)不用多说,这是一个解决方案:
是的,真的很糟糕 . 请参阅我在https://stackoverflow.com/a/50653047/421049的类似文章,其中我提供了对逻辑中发生的事情的更多分析,以及为什么我使用了某些结构 .
可怕 . 我今天必须学习的大部分内容 . 它伤害了 .