在Windows命令行中使用批处理文件中的参数

时间:2013-01-11 20:53:57

标签: windows batch-file cmd parameters arguments

在Windows中,如何访问批处理文件运行时传递的参数?

例如,假设我有一个名为hello.bat的程序。当我在Windows命令行输入hello -a时,如何让我的程序知道-a作为参数传递?

5 个答案:

答案 0 :(得分:268)

正如其他人已经说过的那样,通过命令行传递的参数可以使用符号%1%9的批处理文件进行访问。您还可以使用另外两个令牌:

  • %0 是命令行中指定的可执行文件(批处理文件)
  • %* 命令行中指定的所有参数 - 如果您想将参数转发给其他程序,这非常有用。

除了如何访问参数之外,还有许多重要的技术需要注意。

检查参数是否已通过

这是使用像IF "%~1"==""这样的结构来完成的,当且仅当根本没有传递任何参数时才是真的。请注意波形符号,它会导致任何周围的引号从%1的值中删除;如果该值包含双引号,则包括语法错误的可能性,如果没有波形符号,您将获得意外结果。

处理超过9个参数(或只是让生活更轻松)

如果您需要访问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的类似帖子,在那里我提供了对逻辑中发生的事情的更多分析,以及为什么我使用了某些结构。

丑恶。我今天必须学习的大部分内容。它很痛苦。