在Windows中,如何访问批处理文件运行时传递的参数?
例如,假设我有一个名为hello.bat
的程序。当我在Windows命令行输入hello -a
时,如何让我的程序知道-a
作为参数传递?
答案 0 :(得分:268)
正如其他人已经说过的那样,通过命令行传递的参数可以使用符号%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 /?
来查看所有这些功能。
答案 1 :(得分:51)
使用批处理文件中的参数:%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
是调用的程序名,因此如果在启动时启动,则在DOS %0
中对于AUTOEXEC.BAT将为空。
示例:强>
将以下命令放在名为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
答案 2 :(得分:5)
批处理文件会自动在程序之后传递文本,只要它们是要分配给它们的变量即可。它们被传递以便发送;例如%1将是调用程序后发送的第一个字符串,等等。
如果你有Hello.bat,内容是:
@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause
并通过
调用批处理命令hello.bat APerson241%date%
您应该收到此消息:
您好,APerson241感谢您运行此批处理文件(01/11/2013)
答案 3 :(得分:3)
使用变量,即.BAT
变量,并将%0
称为%9
答案 4 :(得分:1)
@ 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://stackoverflow.com/a/50653047/421049的类似帖子,在那里我提供了对逻辑中发生的事情的更多分析,以及为什么我使用了某些结构。
丑恶。我今天必须学习的大部分内容。它很痛苦。