繁体   English   中英

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

[英]Using parameters in batch files at Windows command line

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

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

正如其他人已经说过的那样,通过命令行传递的参数可以使用符号%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 /?来查看所有这些功能CALL /? 在命令提示符下。

使用批处理文件中的参数:%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

批处理文件会自动在程序之后传递文本,只要它们是要分配给它们的变量即可。 它们被传递以便发送; 例如%1将是调用程序后发送的第一个字符串,等等。

如果你有Hello.bat,内容是:

@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause

并通过命令调用批处理

hello.bat APerson241%date%

你应该收到这封邮件:

您好,APerson241感谢您运行此批处理文件(01/11/2013)

使用变量,即.BAT变量,并调用%0%9

@ Jon's :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上的类似帖子,其中我提供了对逻辑中发生的事情的更多分析,以及为什么我使用了某些结构。

可怕。 我今天必须学习的大部分内容。 它伤害了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM