【问题标题】:How can I pass arguments to a batch file?如何将参数传递给批处理文件?
【发布时间】:2010-09-06 19:03:38
【问题描述】:

我需要在运行时将 ID 和密码传递给批处理文件,而不是将它们硬编码到文件中。

命令行如下所示:

test.cmd admin P@55w0rd > test-log.txt

【问题讨论】:

  • 对于“所有其他人”,请参阅 Greg Hegill 在how to get batch file parameters from Nth position on?的评论
  • 我有一个环境启动脚本,它将我的用户名/密码推送到环境变量中......这样我就不必每次都输入它们......我大部分时间都在使用 bash虽然时间(linux,mac和windows),并且需要将它用于脚本中的代理配置等工作。

标签: batch-file arguments


【解决方案1】:

如果您担心安全/密码被盗(这导致您设计了这个解决方案,该解决方案在执行时获取登录凭据而不是静态硬编码而不需要数据库),那么您可以存储 api 或一半代码程序文件中的密码解密或解密密钥,因此在运行时,如果您正在查看用户输入凭据,用户将在控制台中键入用户名/密码以进行散列/解密,然后通过set /p 传递给程序代码以执行在运行时。

如果您正在运行脚本以使用各种用户/密码运行程序,那么命令行参数将适合您。

如果你正在制作一个测试文件来查看不同登录的输出/效果,那么你可以将所有登录存储在一个加密文件中,作为 arg 传递给 test.cmd,除非你想坐在命令行& 输入所有登录信息,直到完成。

可以提供的参数数量是limited to total characters on command line。为了克服这个限制,上一段的技巧是一种解决方法,不会冒暴露用户密码的风险。

【讨论】:

    【解决方案2】:

    每个人的回答都非常复杂,但实际上非常简单。 %1 %2 %3 等是解析到文件的参数。 %1 是论证 1,%2 是论证 2,依此类推。

    所以,如果我有一个包含以下内容的 bat 脚本:

    @echo off
    echo %1
    

    当我运行批处理脚本时,我输入:

    C:> script.bat Hello
    

    脚本将简单地输出以下内容:

    Hello
    

    这对于脚本中的某些变量非常有用,例如姓名和年龄。所以,如果我有这样的脚本:

    @echo off
    echo Your name is: %1
    echo Your age is: %2
    

    当我输入这个时:

    C:> script.bat Oliver 1000
    

    我得到这个输出:

    Your name is: Oliver
    Your age is: 1000
    

    【讨论】:

    • 很好的答案。简洁易懂。 ?
    【解决方案3】:

    为了使用循环获取所有参数并在纯批处理中:

    Obs: 不使用:?*&|<>


    @echo off && setlocal EnableDelayedExpansion
    
     for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && (
         call set "_arg_[!_cnt!]=!_arg_!" && for /l %%l in (!_cnt! 1 !_cnt!
         )do echo/ The argument n:%%l is: !_arg_[%%l]!
     )
    
    goto :eof 
    

    您的代码已准备好在需要的地方使用参数编号执行某些操作,例如...

     @echo off && setlocal EnableDelayedExpansion
    
     for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!"
     
     fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt
     
    

    【讨论】:

      【解决方案4】:

      成对参数

      如果您更喜欢在键值对中传递参数,您可以使用如下方式:

      @echo off
      
      setlocal enableDelayedExpansion
      
      :::::  asigning arguments as a key-value pairs:::::::::::::
      set counter=0
      for %%# in (%*) do (    
          set /a counter=counter+1
          set /a even=counter%%2
          
          if !even! == 0 (
              echo setting !prev! to %%#
              set "!prev!=%%~#"
          )
          set "prev=%%~#"
      )
      ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
      
      :: showing the assignments
      echo %one% %two% %three% %four% %five%
      
      endlocal
      

      还有一个例子:

      c:>argumentsDemo.bat one 1 "two" 2 three 3 four 4 "five" 5
      1 2 3 4 5
      

      预定义变量

      也可以提前设置一些环境变量。可以通过在控制台或setting them from my computer中设置它们来完成:

      @echo off
      
      if defined variable1 (
          echo %variable1%
      )
      
      if defined variable2 (
          echo %variable2%
      )
      

      然后这样称呼它:

      c:\>set variable1=1
      
      c:\>set variable2=2
      
      c:\>argumentsTest.bat
      1
      2
      

      列出值的文件

      您还可以指向预设所需值的文件。 如果这是脚本:

      @echo off
      
      setlocal
      ::::::::::
      set "VALUES_FILE=E:\scripts\values.txt"
      :::::::::::
      
      
      for /f "usebackq eol=: tokens=* delims=" %%# in ("%VALUES_FILE%") do set "%%#"
      
      echo %key1% %key2% %some_other_key%
      
      endlocal
      

      值文件是这样的:

      :::: use EOL=: in the FOR loop to use it as a comment
      
      key1=value1
      
      key2=value2
      
      :::: do not left spaces arround the =
      :::: or at the begining of the line
      
      some_other_key=something else
      
      and_one_more=more
      

      调用它的输出是:

      value1 value2 别的东西

      当然,您可以结合所有方法。还要检查arguments syntaxshift

      【讨论】:

        【解决方案5】:

        在批处理文件中

        set argument1=%1
        set argument2=%2
        echo %argument1%
        echo %argument2%
        

        %1%2 分别返回第一个和第二个参数值。

        在命令行中,传递参数

        Directory> batchFileName admin P@55w0rd 
        

        输出将是

        admin
        P@55w0rd
        

        【讨论】:

          【解决方案6】:

          要在命令行中引用设置变量,您需要使用%a%,例如:

          set a=100 
          echo %a%  
          rem output = 100 
          

          注意:这适用于 Windows 7 专业版。

          【讨论】:

            【解决方案7】:

            我是这样做的:

            @fake-command /u %1 /p %2
            

            命令如下所示:

            test.cmd admin P@55w0rd > test-log.txt
            

            %1 适用于第一个参数,%2(这是棘手的部分)适用于第二个参数。以这种方式最多可以传递 9 个参数。

            【讨论】:

            • 如果你和我一样笨,你的大脑一直在寻找echo %1 %2,却被@fake-command 的不可剪切和粘贴的最简单案例所抛弃参数,认为我们稍后会得到fake-command.bat 的内容(在这种情况下,过于复杂的fake-command.bat 可能有echo %2 %4 以忽略参数名称)。 错了,笨蛋。 TL;DR:不要像我一样愚蠢。 1. echo echo %1 %2 > test.bat 2. test word1 word2. 3. 利润。
            • 五年后,我回来阅读我的评论时感到困惑。似乎意味着“创建一个带有两个参数的 .bat,按字面意思输入 echo echo %1 %2 > test.bat。test.bat 文件中将包含 echo %1 %2(您也可以从文本编辑器中保存它)。现在输入 @987654336 @ 调用并查看参数是否有效。word1 word2 将回显到命令行。(echo %2 %4 将忽略 /u/p,因此您可以调用 test /u word1 /p word2 以获得相同的结果) .@ before a cmd in a bat file means the cmd isn't repeated.
            【解决方案8】:

            另一个有用的提示是使用%* 表示“全部”。例如:

            echo off
            set arg1=%1
            set arg2=%2
            shift
            shift
            fake-command /u %arg1% /p %arg2% %*
            

            当你运行时:

            test-command admin password foo bar
            

            上面的批处理文件将运行:

            fake-command /u admin /p password admin password foo bar
            

            我的语法可能有点错误,但这是一般的想法。

            【讨论】:

            • %* 实际上扩展到所有参数,而不管移位。因此,即使在两次轮班之后,您仍然会在 %* 中保留前两个参数。您可以使用类似这样的方法:stackoverflow.com/questions/761615/… 来获取一个包含除前 n 个参数之外的所有内容的变量。
            • 请注意 %* 并非在任何地方都有效!例如,它不适用于 DOSBox 0.73(也许这是一个应该报告的错误)。
            • 这不是一个错误,因为 %* 从来没有在 MS-DOS 或 Win9x 中工作过。
            • 这个答案是错误的。它实际上导致fake-command /u admin /p password admin password foo bar。 @Joey 多年前就指出了这一点。
            • 在这种情况下,这两个班次毫无意义。在它们之后 %1 将变为 foo 并且 %2 将变为 bar 但这不会以任何方式使用并且 %* 不受 shift 命令的影响
            【解决方案9】:

            使用 %1、%2、... %9 或 %* 可以很简单地访问批处理参数,
            但前提是内容简单。

            对于像"&"^& 这样的复杂内容没有简单的方法,因为访问 %1 是不可能不产生错误的。

            set  var=%1
            set "var=%1"
            set  var=%~1
            set "var=%~1"
            

            线条扩展为

            set  var="&"&
            set "var="&"&"
            set  var="&"&
            set "var="&"&"
            

            每一行都失败了,因为 & 之一在引号之外。

            可以通过从临时文件读取参数的remarked版本来解决。

            @echo off
            SETLOCAL DisableDelayedExpansion
            
            SETLOCAL
            for %%a in (1) do (
                set "prompt="
                echo on
                for %%b in (1) do rem * #%1#
                @echo off
            ) > param.txt
            ENDLOCAL
            
            for /F "delims=" %%L in (param.txt) do (
              set "param1=%%L"
            )
            SETLOCAL EnableDelayedExpansion
            set "param1=!param1:*#=!"
            set "param1=!param1:~0,-2!"
            echo %%1 is '!param1!'
            

            诀窍是启用echo on 并在rem 语句之后扩展%1(也适用于%2 .. %*)。
            因此,即使"&"& 也可以被回显而不会产生错误,正如它所指出的那样。

            但要能够重定向echo on 的输出,您需要两个for 循环。

            额外的字符* # 用于防止/? 之类的内容(将显示REM 的帮助)。
            或者行尾的插入符号 ^ 可以用作多行字符,即使在 rem 之后也是如此。

            然后读取文件中的rem参数输出,但要小心。
            FOR /F 应该在延迟扩展关闭的情况下工作,否则内容为“!”会被摧毁。
            去掉param1中多余的字符后,就明白了。

            为了安全地使用param1,启用延迟扩展。

            【讨论】:

            • for /F "tokens=*" %%a in ('echo %*') do set "all_args=%%a"
            • @KevinEdwards 然后尝试使用&,您的解决方案仅适用于简单内容
            • @KevinEdwards 我测试了它,test.bat ^&,但它失败了。只有test.bat "&" 有效,但这不是我的意思。如果没有 REM 技术,您将无法安全地使用 %*%1
            • 啊,是的,插入符号不能正确地转义它。您需要引号,这对于我遇到的所有用例都是可行的。我只是想把它传下去。感谢您对其进行测试!干杯:)
            • @jwdonahue 是的,这很复杂(但并不过分复杂)。但特别是对于密码,它可能是必要的,至少我的一些密码包含与符号& 和引号"
            【解决方案10】:

            简单的解决方案(即使问题很旧)

            Test1.bat

            echo off
            echo "Batch started"
            set arg1=%1
            echo "arg1 is %arg1%"
            echo on
            pause
            

            CallTest1.bat

            call "C:\Temp\Test1.bat" pass123
            

            输出

            YourLocalPath>call "C:\Temp\test.bat" pass123
            
            YourLocalPath>echo off
            "Batch started"
            "arg1 is pass123"
            
            YourLocalPath>pause
            Press any key to continue . . .
            

            YourLocalPath 是当前目录路径。

            为了简单起见,将命令参数存储在变量中并使用变量进行比较。

            它不仅写起来简单,而且维护起来也很简单,所以如果以后有人或你在很长一段时间后阅读你的脚本,它就会很容易理解和维护。

            内联代码:查看其他答案。

            【讨论】:

              【解决方案11】:

              受@Jon 的answer elsewhere 启发,我设计了一个更通用的算法来提取命名参数、可选值和开关。

              假设我们要实现一个实用程序foobar。它需要一个初始命令。它有一个可选参数--foo,它接受一个可选值(当然不能是另一个参数);如果缺少该值,则默认为default。它还有一个可选参数 --bar,它采用 required 值。最后,它可以带一个标志--baz,但不允许使用任何值。哦,这些参数可以按任意顺序出现。

              换句话说,它看起来像这样:

              foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
              

              这里有一个解决方案:

              @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
              
              • 使用SETLOCAL,这样变量就不会逃到调用环境中。
              • 不要忘记初始化变量SET FOO=等,以防有人在调用环境中定义它们。
              • 使用%~1 删除引号。
              • 使用IF "%ARG%" == "" 而不是IF [%ARG%] == [],因为[] 根本不会使用以空格结尾的值。
              • 即使您在IF 块内SHIFT,当前参数(例如%~1)也不会更新,因为它们是在解析IF 时确定的。您可以在IF 块内使用%~1%~2,但这会令人困惑,因为您有一个SHIFT。为了清楚起见,您可以将SHIFT 放在块的末尾,但这也可能会丢失和/或混淆人们。所以在街区外“捕获”%~1%~1 似乎最好。
              • 你不想用一个参数代替另一个参数的可选值,所以你必须检查IF NOT "%ARG:~0,2%" == "--"
              • 当您使用其中一个参数时,请注意SHIFT
              • 重复代码SET FOO=%DEFAULT_FOO% 令人遗憾,但替代方法是在IF NOT "%ARG%" == "" 块之外添加IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%。然而,因为它仍然在 IF "%PARAM%" == "--foo" 块内,所以 %FOO% 值会在你进入块之前被评估和设置,所以你永远不会检测到 both --foo 参数是表示 并且 %FOO% 值丢失。
              • 请注意,ECHO Missing bar value. 1&gt;&amp;2 将错误消息发送到 stderr。
              • 想在 Windows 批处理文件中有一个空行吗?您必须使用 ECHO: 或其中一种变体。

              【讨论】:

                【解决方案12】:

                最近有朋友问我这个问题,所以我想我会发布我如何处理批处理文件中的命令行参数。

                正如您将看到的那样,这种技术有一些开销,但它使我的批处理文件非常容易理解并且可以快速实现。以及支持以下结构:

                >template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]
                

                它的要点是具有:init:parse:main 函数。

                示例用法

                >template.bat /?
                test v1.23
                This is a sample batch file template,
                providing command-line arguments and flags.
                
                USAGE:
                test.bat [flags] "required argument" "optional argument"
                
                /?, --help           shows this help
                /v, --version        shows the version
                /e, --verbose        shows detailed output
                -f, --flag value     specifies a named parameter value
                
                >template.bat          <- throws missing argument error
                (same as /?, plus..)
                ****                                   ****
                ****    MISSING "REQUIRED ARGUMENT"    ****
                ****                                   ****
                
                >template.bat -v
                1.23
                
                >template.bat --version
                test v1.23
                This is a sample batch file template,
                providing command-line arguments and flags.
                
                >template.bat -e arg1
                **** DEBUG IS ON
                UnNamedArgument:    "arg1"
                UnNamedOptionalArg: not provided
                NamedFlag:          not provided
                
                >template.bat --flag "my flag" arg1 arg2
                UnNamedArgument:    "arg1"
                UnNamedOptionalArg: "arg2"
                NamedFlag:          "my flag"
                
                >template.bat --verbose "argument #1" --flag "my flag" second
                **** DEBUG IS ON
                UnNamedArgument:    "argument #1"
                UnNamedOptionalArg: "second"
                NamedFlag:          "my flag"
                

                模板.bat

                @::!/dos/rocks
                @echo off
                goto :init
                
                :header
                    echo %__NAME% v%__VERSION%
                    echo This is a sample batch file template,
                    echo providing command-line arguments and flags.
                    echo.
                    goto :eof
                
                :usage
                    echo USAGE:
                    echo   %__BAT_NAME% [flags] "required argument" "optional argument" 
                    echo.
                    echo.  /?, --help           shows this help
                    echo.  /v, --version        shows the version
                    echo.  /e, --verbose        shows detailed output
                    echo.  -f, --flag value     specifies a named parameter value
                    goto :eof
                
                :version
                    if "%~1"=="full" call :header & goto :eof
                    echo %__VERSION%
                    goto :eof
                
                :missing_argument
                    call :header
                    call :usage
                    echo.
                    echo ****                                   ****
                    echo ****    MISSING "REQUIRED ARGUMENT"    ****
                    echo ****                                   ****
                    echo.
                    goto :eof
                
                :init
                    set "__NAME=%~n0"
                    set "__VERSION=1.23"
                    set "__YEAR=2017"
                
                    set "__BAT_FILE=%~0"
                    set "__BAT_PATH=%~dp0"
                    set "__BAT_NAME=%~nx0"
                
                    set "OptHelp="
                    set "OptVersion="
                    set "OptVerbose="
                
                    set "UnNamedArgument="
                    set "UnNamedOptionalArg="
                    set "NamedFlag="
                
                :parse
                    if "%~1"=="" goto :validate
                
                    if /i "%~1"=="/?"         call :header & call :usage "%~2" & goto :end
                    if /i "%~1"=="-?"         call :header & call :usage "%~2" & goto :end
                    if /i "%~1"=="--help"     call :header & call :usage "%~2" & goto :end
                
                    if /i "%~1"=="/v"         call :version      & goto :end
                    if /i "%~1"=="-v"         call :version      & goto :end
                    if /i "%~1"=="--version"  call :version full & goto :end
                
                    if /i "%~1"=="/e"         set "OptVerbose=yes"  & shift & goto :parse
                    if /i "%~1"=="-e"         set "OptVerbose=yes"  & shift & goto :parse
                    if /i "%~1"=="--verbose"  set "OptVerbose=yes"  & shift & goto :parse
                
                    if /i "%~1"=="--flag"     set "NamedFlag=%~2"   & shift & shift & goto :parse
                
                    if not defined UnNamedArgument     set "UnNamedArgument=%~1"     & shift & goto :parse
                    if not defined UnNamedOptionalArg  set "UnNamedOptionalArg=%~1"  & shift & goto :parse
                
                    shift
                    goto :parse
                
                :validate
                    if not defined UnNamedArgument call :missing_argument & goto :end
                
                :main
                    if defined OptVerbose (
                        echo **** DEBUG IS ON
                    )
                
                    echo UnNamedArgument:    "%UnNamedArgument%"
                
                    if defined UnNamedOptionalArg      echo UnNamedOptionalArg: "%UnNamedOptionalArg%"
                    if not defined UnNamedOptionalArg  echo UnNamedOptionalArg: not provided
                
                    if defined NamedFlag               echo NamedFlag:          "%NamedFlag%"
                    if not defined NamedFlag           echo NamedFlag:          not provided
                
                :end
                    call :cleanup
                    exit /B
                
                :cleanup
                    REM The cleanup function is only really necessary if you
                    REM are _not_ using SETLOCAL.
                    set "__NAME="
                    set "__VERSION="
                    set "__YEAR="
                
                    set "__BAT_FILE="
                    set "__BAT_PATH="
                    set "__BAT_NAME="
                
                    set "OptHelp="
                    set "OptVersion="
                    set "OptVerbose="
                
                    set "UnNamedArgument="
                    set "UnNamedArgument2="
                    set "NamedFlag="
                
                    goto :eof
                

                【讨论】:

                  【解决方案13】:

                  没有必要把它复杂化。它只是命令 %1 %2 参数,例如,

                  @echo off
                  
                  xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z
                  
                  echo copied %1 to %2
                  
                  pause
                  

                  “暂停”显示批处理文件已完成的操作并等待您按 ANY 键。在 Windows 文件夹中将其另存为 xx.bat。

                  要使用它,请输入,例如:

                  xx c:\f\30\*.* f:\sites\30
                  

                  这个批处理文件负责所有必要的参数,比如只复制文件、更新的文件等。我在 Windows 之前就使用过它。如果您喜欢在复制文件时查看文件的名称,请忽略 Q 参数。

                  【讨论】:

                    【解决方案14】:
                    @ECHO OFF
                    :Loop
                    IF "%1"=="" GOTO Continue
                    SHIFT
                    GOTO Loop
                    :Continue
                    

                    注意:如果%1 本身用引号括起来,IF "%1"=="" 会导致问题。

                    在这种情况下,请使用IF [%1]==[],或者仅在 NT 4 (SP6) 及更高版本中,使用IF "%~1"==""

                    【讨论】:

                    • 确实如此,但它几乎没有触及主题。
                    【解决方案15】:

                    我编写了一个简单的 read_params 脚本,它可以作为函数(或外部.bat)调用,并将所有变量放入当前环境。它不会修改原始参数,因为该函数正在使用原始参数的副本called。

                    例如,给定以下命令:

                    myscript.bat some -random=43 extra -greeting="hello world" fluff
                    

                    myscript.bat 调用函数后就可以使用变量了:

                    call :read_params %*
                    
                    echo %random%
                    echo %greeting%
                    

                    函数如下:

                    :read_params
                    if not %1/==/ (
                        if not "%__var%"=="" (
                            if not "%__var:~0,1%"=="-" (
                                endlocal
                                goto read_params
                            )
                            endlocal & set %__var:~1%=%~1
                        ) else (
                            setlocal & set __var=%~1
                        )
                        shift
                        goto read_params
                    )
                    exit /B
                    

                    限制

                    • 无法加载没有值的参数,例如-force。您可以使用-force=true,但我想不出一种方法来允许空白值,而无需提前知道没有值的参数列表。

                    更新日志

                    • 2016 年 2 月 18 日
                      • 不再需要延迟扩展
                      • 现在可以通过在参数前查找 - 来处理其他命令行参数。

                    【讨论】:

                    • 一直在研究使用这种方法,因为我想以这种方式将参数传递到批处理文件中。但是我注意到,在设置变量之后,即使在退出批处理文件之后,如果访问并且批处理已经结束,参数仍然在 cmd 中设置,它们不会恢复到以前的状态。这种方法应该处理这种情况吗?
                    • 在主题上,比这个线程上的其他一些答案更好。
                    • 扩展它以支持标志参数(无值)。抱歉,缺少格式,但它在 cmets 中不起作用:read_params if not %1/==/ ( if not "%__var%"=="" ( if not "%__var:~0,1%"== "-" (endlocal goto read_params) endlocal & set %__var:~1%=%~1) else (setlocal & set __var=%~1) shift goto read_params) else (if not "%__var%"=="" ( endlocal & set %__var:~1%=1 ) )
                    【解决方案16】:

                    让我们保持简单。

                    这是 .cmd 文件。

                    @echo off
                    rem this file is named echo_3params.cmd
                    echo %1
                    echo %2
                    echo %3
                    set v1=%1
                    set v2=%2
                    set v3=%3
                    echo v1 equals %v1%
                    echo v2 equals %v2%
                    echo v3 equals %v3%
                    

                    这里有 3 个来自命令行的调用。

                    C:\Users\joeco>echo_3params 1abc 2 def  3 ghi
                    1abc
                    2
                    def
                    v1 equals 1abc
                    v2 equals 2
                    v3 equals def
                    
                    C:\Users\joeco>echo_3params 1abc "2 def"  "3 ghi"
                    1abc
                    "2 def"
                    "3 ghi"
                    v1 equals 1abc
                    v2 equals "2 def"
                    v3 equals "3 ghi"
                    
                    C:\Users\joeco>echo_3params 1abc '2 def'  "3 ghi"
                    1abc
                    '2
                    def'
                    v1 equals 1abc
                    v2 equals '2
                    v3 equals def'
                    
                    C:\Users\joeco>
                    

                    【讨论】:

                      【解决方案17】:

                      制作一个新的批处理文件(例如:openclass.bat)并在文件中写入这一行:

                      java %~n1
                      

                      然后将批处理文件放在system32文件夹中,转到您的Java类文件,右键单击,属性,打开方式...,然后找到您的批处理文件,选择它,就是这样...

                      它对我有用。

                      PS:当我关闭 Java 类时,我找不到关闭 cmd 窗口的方法。暂时……

                      【讨论】:

                      • 您可以在进程关闭后在批处理脚本中使用以下命令关闭 cmd 窗口:start /wait java %~n1
                      • 劝人随意把脚本文件放到system32目录下是不负责任的。这个答案确实没有触及这个线程主题的表面。
                      【解决方案18】:
                      FOR %%A IN (%*) DO (
                          REM Now your batch file handles %%A instead of %1
                          REM No need to use SHIFT anymore.
                          ECHO %%A
                      )
                      

                      这会遍历批处理参数 (%*),无论它们是否被引用,然后回显每个参数。

                      【讨论】:

                      • 但是由于许多不同的参数而失败,例如 test.bat *.txttest.bat cat^&amp;dogTest.bat /?
                      【解决方案19】:

                      如果您想智能地处理丢失的参数,您可以执行以下操作:

                      IF %1.==. GOTO No1
                      IF %2.==. GOTO No2
                      ... do stuff...
                      GOTO End1
                      
                      :No1
                        ECHO No param 1
                      GOTO End1
                      :No2
                        ECHO No param 2
                      GOTO End1
                      
                      :End1
                      

                      【讨论】:

                      • 点/句点在这些相等运算中有什么意义?
                      • 基本上如果 %1 为空,这将最终成为 IF 。 == 。所以 GOTO 会发生。我们在这里使用 x:IF x%1 == x -> IF x==x -> true
                      • 您应该询问“未提供的参数”的价值是什么?您应该检查“未提供的论点”吗?然后,如果你没有答案,你应该使用像点之一这样的技巧。请记住,就像这里所说的ss64.com/nt/if.html“实际上,您几乎可以使用任何字符来表示‘~’或花括号、{} 甚至数字 4,但倾向于选择方括号,因为它们没有任何特殊含义。”
                      【解决方案20】:

                      是的,只是不要忘记在使用 iffor 时使用像 %%1 这样的变量。

                      如果您忘记了双 %,那么您将替换为(可能为 null)命令行参数,您将收到一些非常混乱的错误消息。

                      【讨论】:

                      • %% 仅适用于iffor ?
                      • 比这更糟糕 - %% 用于在 inside 批处理文件中为变量和命令行参数添加前缀。但是当您从命令行使用这些命令时,您只使用 % 作为前缀。示例:批次内:for %%d in (*) do echo %%d 从命令行:for %d in (*) do echo %d
                      • @SteveMidgley 我大概在一年前对你的评论投了赞成票。然后我很快就忘记了它,就在今天,我正在尝试并困惑地盯着命令行中的 for 循环,想知道为什么它放屁而什么也没做。所以这是我的另一个虚拟支持。当我再次遇到同样的问题时,我会再过一年左右。
                      • 我们通常为命令行处理保留数字,据我所知,双百分号仅适用于 for 语句。 @for %%2 in (testing) do @echo %%2 %1 在批处理文件中,当使用 1 (test 1) 调用它时生成 testing 1
                      • 答案是错误的。 %%1 不访问命令行参数,IF 命令也是错误的。只有FOR 命令(在批处理文件中)需要双百分号,但即使这样%%1 也会定义一个 FOR 参数并且不访问参数
                      猜你喜欢
                      • 1970-01-01
                      • 2018-03-28
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-07-03
                      • 2014-01-04
                      • 2021-01-11
                      相关资源
                      最近更新 更多