首页 文章

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

提问于
浏览
144

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

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

5 回答

  • 5

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

    • %0the 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 . 在这种情况下解析命令行的好方法是

    :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

    Using parameters in batch files: %0 and %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将为空,如果在启动时启动的话 .

    Example:

    将以下命令放在名为 mybatch.bat 的批处理文件中:

    @echo off
    @echo hello %1 %2
    pause
    

    像这样调用批处理文件: mybatch john billy 将输出:

    hello 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版本,是否“转义”,并且通常取决于它们在命令行中的位置:

    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
    
  • 49

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

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

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

    并通过命令调用批处理

    hello.bat APerson241%date%

    你应该收到这封邮件:

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

  • 262

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

  • 3

    @ 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的类似文章,其中我提供了对逻辑中发生的事情的更多分析,以及为什么我使用了某些结构 .

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

相关问题