【问题标题】:Is there a way to create a CMD command with arguments?有没有办法创建带有参数的 CMD 命令?
【发布时间】:2020-07-02 16:02:40
【问题描述】:

我正在尝试在命令提示符下创建一个命令,但使用的参数就像你可以使用另一种语言的函数一样。

例如,您可以在 C:\Windows\System32 文件夹中创建一个批处理文件,并在命令提示符下键入其名称来执行它,从而创建一个“命令”。不过,这非常简单,只需运行批处理文件包含的任何内容。

我的命令叫做toolbx,它在命令提示符中有不同的有用快捷键。但是,我想通过键入 toolbx 1 之类的内容来执行不同的工具。这可能是它的样子。

toolbx [input received changing what tool you want to use] (e.g. 1)

在 toolbx.bat 中

if %inputRecieved% == 1 goto 1

我不擅长解释,所以 Python 中的另一个例子可能是:

def functionWithArgs (tool)

执行为:

functionWithArgs(1)

作为另一个总结:

我正在尝试使用批处理文件制作命令提示符中使用的命令

我希望批处理文件在命令运行时定义参数(如 python 示例),这些参数可用作批处理文件中的变量。

提前谢谢你!

【问题讨论】:

  • 输入 set /?call /?cmd /? 寻求帮助。
  • 您可以使用functions,但您要查找的似乎是macros

标签: batch-file cmd arguments command


【解决方案1】:

今天是你的幸运日,windows 批处理文件确实支持一个名为命令行参数的功能。以下是您需要做的:

set inputRecieved=%1
if "%inputRecieved%"=="1" goto label1
goto :eof

:label1
   blabla...

玩得开心!

附言

请注意单词的正确拼写是“received”,而不是“received”。

【讨论】:

  • 谢谢!我完全错过了收到的错误拼写。我将进一步研究命令行参数。
【解决方案2】:

您可以使用 @jeb@dbenham 和 DosTips 用户 @Ed Dyreen 发明的macro style

定义:

@echo off
SETLOCAL DISABLEDELAYEDEXPANSION

::Definitions
( set LF=^
%= EMPTY =%
)
set ^"NL=^^^%LF%%LF%^%LF%%LF%^^"

整个目的是创建一个 multiline 变量。见batch newline variable hack

主宏:

::Macro
ENDLOCAL &^
set $MACRO.Toolbx=FOR %%a in (args main) do if "%%a" == "main" (%NL%
    for %%A in (%payload%) do (%NL%
        %= MAIN MACRO HERE, END LINES WITH NL =%%NL%
    )%NL%
) ELSE SETLOCAL ENABLEDELAYEDEXPANSION ^& set args=,

exit /b

另存为MACRO.Toolbx.bat。要在批处理文件中使用宏:

call MACRO.Toolbx.bat
%$MACRO.Toolbx% COMMAND_LINE_ARGS

宏使用巧妙的FOR 循环来“捕捉”参数。另外,为了捕捉参数,DISABLEDELAYEDEXPANSION 是必须的,这与SETLOCAL 密不可分。但是,ENDLOCAL 将销毁该范围内的所有用户定义变量,但我们需要换行定义。因此,ENDLOCAL 和宏定义必须在同一行。这种技术称为ENDLOCAL tunneling

【讨论】:

    【解决方案3】:

    确定 【完整路径和文件名】【参数1】【参数2】【and_so_on】

    是分隔参数的空格,可以用 %1 %2 %3...

    您可以使用 %* 扩展所有参数或最多单独扩展 9 个参数 例如:

    %windir%\system32\toolbx.cmd Tool_1
    

    注意传递的参数是:Tool_1

    在下面的示例中,在第 2 行使用了 %1 扩展:Tool_1

    setlocal EnableDelayedExpansion
    set tool=%1
    set argument_1=Have
    set argument_2=a
    set argument_3=Nice
    set argument_4=Day
    CALL :Function_%tool% argument_1 argument_2 argument_3 argument_4
    :: after Function_Tool_1 ends by reading the next GOTO :EOF after its Label,
    :: will return to read instructions after this line
    ::
    pause&&exit
    ::
    :Function_Tool_1
    echo. %argument_1% %argument_2% %argument_3% %argument_4% 
    goto :EOF
    ::
    ::
    

    注意:

    使用CALL调用标签时,必须使用冒号,例如:

    CALL :YourLabel
    

    标签后面的所有参数或参数用空格隔开 例如:

    CALL :YourLabel param1 param2 param3 parampampam etc
    

    我认为标签的语法与变量的语法相同。

    您必须使用 GOTO :EOF 来结束函数或过程

    例如,使用 GOTO 转到标签时,请注意不要使用冒号:

    GOTO YourLabel
    

    但是当使用 CALL 时不同,这解释得更好:

    EXIT /?
    
    GOTO /?
    

    &用于分隔指令

    && 用于将批处理文件中的指令分隔为 toolbx.cmd

    在上面的例子中还要注意: %1 %2 %3 和 %4 沿函数可以扩展变量名,例如:

    echo. %1 %2 %3 %4
    

    会回显:argument_1argument_2argument_3argument_4

    并使用 SETLOCAL EnableDelayedExpansion

    !%1!可以扩展变量的值,例如:

    echo. !%1! !%2! !%3! !%4!
    

    会回应:祝你有美好的一天

    【讨论】:

      【解决方案4】:

      使用for 循环开发了一种技术,该技术允许在扩展变量时捕获参数 - 批处理宏。

      使用了一个外部 for 循环,它在第一次迭代时分配一个包含参数值的变量,内部循环处理并作用于这些值。

      @echo off
      Set "Macroname=For %%n in (1 2)Do if %%n==2 (Echo(!Args!)Else Set args="
      Setlocal EnableDelayedExpansion
      %Macroname% Hello World
      

      该技术需要在延迟扩展为disabled 的环境中定义宏变量,然后使用Setlocal EnableDelayedExpansion 启用宏。 (当然,除非所有! 扩展符号在启用延迟扩展的环境的宏定义期间都被正确转义。)

      下面是批处理宏的模板,它构建一个 Args 数组并处理尾随参数的开关。模板的目的是通过准备好所有参数和开关处理逻辑来允许快速编写高级函数的脚本,这样函数的主体就是需要编写脚本的全部内容。

      参数返回到数组$Macroname_args[!$Macroname_args[i]!],其中:
      !$Macroname_args[i]! 是参数的 0 索引计数。
      使用开关字符串作为索引在关联变量中返回开关 IE:
      %MacroName% /A
      结果:!$Macroname_Switch[A]!==true
      或者,如果提供了子参数:
      %MacroName% /A sub arg
      结果:!$Macroname_Switch[A]!==sub arg

      宏使用 Substring 修改将开关与 args 和进程开关分开。
      因此,arg 或 switch 值包含以下字符:
      = * / "
      应以替换形式提供:
      {EQ} {AS} {FS} {DQ},使用宏内置的替换来替换。

      @Echo off
      
      (Set \n=^^^
      
      %= \n macro newline variable. Do not modify =%)
      (Set LF=^
      
      
      %= LF newline variable. Do not modify =%)
      
      :# Example Switches for demonstrating concept. List used twice within macro switch handling. Define outside macro to
      :# simplify maintainance.
       Set $MacroName_Switches="A" "B" "C" "D" "E" "Def"
      
       Set $MacroName=For %%n in (1 2)Do if %%n==2 (%\n%
        For /F "Tokens=1,2 Delims==" %%G in ('Set "$Macroname_Arg[" 2^^^> nul')Do Set "%%~G="%\n%
        For %%G in ( %$MacroName_Switches% )Do Set "$MacroName_Switch[%%~G]="%\n%
        If not "!$MacroName_args:* /=!" == "!$MacroName_args!" (%\n: build $MacroName.Args[!$MacroName_arg[i]!] array if args present =%
         Set "$MacroName_leading.args=!$MacroName_args:*/=!"%\n%
         For /F "Delims=" %%G in ("!$MacroName_leading.args!")Do Set "$MacroName_leading.args=!$MacroName_args:/%%G=!"%\n%
         Set ^"$MacroName_args=!$MacroName_args:"=!"%\n%
         Set "$MacroName_arg[i]=0"%\n%
         For %%G in (!$MacroName_leading.args!)Do (%\n%
          Set /A "$MacroName_arg[i]+=1"%\n%
          Set "$MacroName_arg[!$MacroName_arg[i]!]=%%~G"%\n%
          For %%i in ("!$MacroName_arg[i]!")Do (%\n%
           Set "$MacroName_arg[%%~i]=!$MacroName_arg[%%~i]:{FS}=/!"%\n%
           Set "$MacroName_arg[%%~i]=!$MacroName_arg[%%~i]:{AS}=*!"%\n%
           Set "$MacroName_arg[%%~i]=!$MacroName_arg[%%~i]:{EQ}==!"%\n%
           Set ^"$MacroName_arg[%%~i]=!$MacroName_arg[%%~i]:{DQ}="!"%\n%
          )%\n%
         )%\n%
        ) Else (%\n: remove doublequotes from args before switch processing switches =%
         Set ^"$MacroName_args=!$MacroName_args:"=!"%\n%
        )%\n%
        Set "$MacroName_LastSwitch="%\n%
        For /L %%L in (2 1 4)Do If "!$MacroName_LastSwitch!" == "" (%\n%
         If "!$MacroName_Args:~-%%L,1!" == " " Set "$MacroName_LastSwitch=_"%\n%
         If "!$MacroName_Args:~-%%L,1!" == "/" (%\n: Flag last switch true if no subargs; Works for character switches of up to 3 characters =%
          For /F "Delims=" %%v in ('Set /A "%%L-1"')Do Set "$MacroName_Switch[!$MacroName_Args:~-%%v!]=true"%\n%
          If not "!$MacroName_Args:/?=!." == "!$MacroName_Args!." Set "$MacroName_Switch[help]=true"%\n%
          Set "$MacroName_Args=!$MacroName_Args:~0,-%%L!"%\n%
          Set "$MacroName_LastSwitch=_"%\n%
         )%\n%
        )%\n%
        For %%G in ( %$MacroName_Switches% )Do If not "!$MacroName_args:/%%~G =!" == "!$MacroName_args!" (%\n%
         Set "$MacroName_Switch[%%~G]=!$MacroName_Args:*/%%~G =!"%\n%
         If not "!$MacroName_Switch[%%~G]:*/=!" == "!$MacroName_Switch[%%~G]!" (%\n%
          Set "$MacroName_Trail[%%~G]=!$MacroName_Switch[%%~G]:*/=!"%\n%
          For %%v in ("!$MacroName_Trail[%%~G]!")Do (%\n%
           Set "$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]: /%%~v=!"%\n%
           Set "$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]:/%%~v=!"%\n%
          )%\n%
          Set "$MacroName_Trail[%%~G]="%\n%
          If "!$MacroName_Switch[%%~G]:~-1!" == " " Set "$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]:~0,-1!"%\n%
          If "!$MacroName_Switch[%%~G]!" == "" Set "$MacroName_Switch[%%~G]=true"%\n%
          If not "!$MacroName_Switch[%%~G]!" == "" If not "!$MacroName_Switch[%%~G]!" == "true" (%\n%
           Set "$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]:{FS}=/!"%\n%
           Set "$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]:{AS}=*!"%\n%
           Set "$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]:{EQ}==!"%\n%
           Set ^"$MacroName_Switch[%%~G]=!$MacroName_Switch[%%~G]:{DQ}="!"%\n%
          )%\n%
         )%\n%
        )%\n: Insert Switch Assessment Below. Use conditional testing of valid switches to enact macro functions before $MacroName_args assignment =%
        REM INSERT COMMANDS BETWEEN THE ABOVE AND BELOW LINES TERMINATING EACH WITH \n VARIABLE %\n%
        %= EXAMPLE. Remove this line. =% Echo(!LF!Example: %%$Macroname%%!$Macroname_args!%\n%
        %= EXAMPLE. Remove this line. =% Set $Macroname_Arg[%\n%
        %= EXAMPLE. Remove this line. =% Set $Macroname_Switch[%\n%
       %= ESCAPE AMPERSANDS AND REDIRECTION CHARACTERS DURING MACRO DEFINITION. =%) Else Set $MacroName_args=
      
      
      Setlocal enableDelayedExpansion
      
      :# Proof of concept
      %$Macroname% "{AS} param 1 {EQ} {DQ}https:{FS}{FS}stackoverflow.com{FS}posts{FS}60793679{DQ}" "param 2" /C one /D 12 /Def
      %$Macroname% /B a b /E /Def "hello world & ^! > < | %%" /A 1 + 2 {EQ} 3 /Undefined switch
      
      

      【讨论】:

        猜你喜欢
        • 2017-05-18
        • 1970-01-01
        • 2014-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-30
        • 1970-01-01
        相关资源
        最近更新 更多