获取Windows批处理脚本(.bat)中传递参数的列表

我想find一个Bash的$@的Windows批处理对象,它包含了所有传入脚本的参数列表。

或者我不得不担心shift

dancavallaro是正确的, %*的一切。 这些对你也可能有用:

%0 – 用于调用batch file的命令(可以是foo..\fooc:\bats\foo等)
%1是第一个命令行参数,
%2是第二个命令行参数,
依此类推直到%9%9日后可用SHIFT )。

%~nx0 – batch file的实际名称,不pipe调用方法(some-batch.bat)
%~dp0 – 驱动器和脚本path(d:\ scripts)
%~dpnx0 – 是脚本的完全限定path名(d:\ scripts \ some-batch.bat)

更多信息请参见http://www.ss64.com/nt/syntax-args.html和http://www.robvanderwoude.com/parameters.html

%*似乎包含传递给脚本的所有参数。

%1%n%*保存参数,但访问它们可能会非常棘手,因为内容将被解释。
因此,用正常的语句来处理这样的事情是不可能的

 myBatch.bat "&"^& 

每行失败,因为cmd.exe尝试执行其中一个&符号(%1的内容是"&"&

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

但是,临时文件存在解决方法

 @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!' 

诀窍是在rem语句之后启用echo on并展开%1 (与%2 ..%*一起使用)。
但是为了能够redirectecho on的输出,你需要两个FOR-LOOPS。

额外的字符* #被用来保护像/?这样的内容/? (会显示REM的帮助)。
或者在行尾的插入符号可以用作多行字符。

FOR / F应该用延迟扩展工作,否则内容为“!” 将被销毁。
删除param1的多余字符后,就可以得到它了。

并且以安全的方式使用param1 ,启用延迟扩展。

编辑:对%0的一个评论

%0包含用于调用批处理的命令,也像FoO.BaT一样保留大小写
但是在函数%0%~0的调用中包含函数名称(或者更好的是用来调用函数的string)之后。
但是用%~f0你仍然可以调用文件名。

 @echo off echo main %0, %~0, %~f0 call :myLabel+xyz exit /b :MYlabel echo func %0, %~0, %~f0 exit /b 

产量

 main test.bat, test.bat, C:\temp\test.bat func :myLabel+xyz, :myLabel+xyz, C:\temp\test.bat 

我发现下一次你需要查看这些信息。 而不是打开浏览器和谷歌,你可以只inputcall /? 在你的CMD,你会得到它:

 ... %* in a batch script refers to all the arguments (eg %1 %2 %3 %4 %5 ...) Substitution of batch parameters (%n) has been enhanced. You can now use the following optional syntax: %~1 - expands %1 removing any surrounding quotes (") %~f1 - expands %1 to a fully qualified path name %~d1 - expands %1 to a drive letter only %~p1 - expands %1 to a path only %~n1 - expands %1 to a file name only %~x1 - expands %1 to a file extension only %~s1 - expanded path contains short names only %~a1 - expands %1 to file attributes %~t1 - expands %1 to date/time of file %~z1 - expands %1 to size of file %~$PATH:1 - searches the directories listed in the PATH environment variable and expands %1 to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string The modifiers can be combined to get compound results: %~dp1 - expands %1 to a drive letter and path only %~nx1 - expands %1 to a file name and extension only %~dp$PATH:1 - searches the directories listed in the PATH environment variable for %1 and expands to the drive letter and path of the first one found. %~ftza1 - expands %1 to a DIR like output line In the above examples %1 and PATH can be replaced by other valid values. The %~ syntax is terminated by a valid argument number. The %~ modifiers may not be used with %* 

检索所有参数到脚本的方法如下:

 @ECHO off ECHO The %~nx0 script args are... for %%I IN (%*) DO ECHO %%I pause 

这是一个相当简单的方法来获取参数并将其设置为envvariables。 在这个例子中,我将把它们称为键和值。

将下面的代码示例保存为“args.bat”。 然后调用从命令行保存的batch file。 例如:arg.bat –x 90 –y 120

我已经提供了一些echo命令来指导您完成整个过程。 但最终的结果是,-x将具有90的值,而-y将具有120的值(即,如果运行上面指定的示例;-))。

然后,您可以使用“if defined”条件语句来确定是否运行您的代码块。 所以让我们说run:“arg.bat –x hello-world”然后我可以使用语句“IF DEFINED –x echo% – x%”,结果是“hello-world”。 如果你运行批处理应该更有意义。

 @setlocal enableextensions enabledelayedexpansion @ECHO off ECHO. ECHO :::::::::::::::::::::::::: arg.bat example ::::::::::::::::::::::::::::::: ECHO :: By: Gary L. Baird, 2013-07-29 :: ECHO :: Version: 1.0 :: ECHO :: Purpose: Checks the args passed to the batch. :: ECHO :: :: ECHO :: Start by gathering all the args with the %%* in a for loop. :: ECHO :: :: ECHO :: Now we use a 'for' loop to search for our keys which are identified :: ECHO :: by the text '--'. The function then sets the --arg ^= to the next :: ECHO :: arg. "CALL:Function_GetValue" ^<search for --^> ^<each arg^> :: ECHO :: :: ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO :: From the command line you could pass... arg.bat --x 90 --y 220 :: ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. ECHO.Checking Args:"%*" FOR %%a IN (%*) do ( CALL:Function_GetValue "--","%%a" ) ECHO. ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO :: Now lets check which args were set to variables... :: ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO :: For this we are using the CALL:Function_Show_Defined "--x,--y,--z" :: ECHO :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. CALL:Function_Show_Defined "--x,--y,--z" endlocal goto done :Function_GetValue REM First we use find string to locate and search for the text. echo.%~2 | findstr /C:"%~1" 1>nul REM Next we check the errorlevel return to see if it contains a key or a value REM and set the appropriate action. if not errorlevel 1 ( SET KEY=%~2 ) ELSE ( SET VALUE=%~2 ) IF DEFINED VALUE ( SET %KEY%=%~2 ECHO. ECHO ::::::::::::::::::::::::: %~0 :::::::::::::::::::::::::::::: ECHO :: The KEY:'%KEY%' is now set to the VALUE:'%VALUE%' :: ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. ECHO %KEY%=%~2 ECHO. REM It's important to clear the definitions for the the key and value in order to REM search for the next key value set. SET KEY= SET VALUE= ) GOTO:EOF :Function_Show_Defined ECHO. ECHO ::::::::::::::::::: %~0 :::::::::::::::::::::::::::::::: ECHO :: Checks which args were defined ie %~2 ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. SET ARGS=%~1 for %%s in (%ARGS%) DO ( ECHO. ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO :: For the ARG: '%%s' IF DEFINED %%s ( ECHO :: Defined as: '%%s=!%%s!' ) else ( ECHO :: Not Defined '%%s' and thus has no value. ) ECHO ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ECHO. ) goto:EOF :done 

下面的代码模拟一个数组(' params ') – 接收脚本接收到的参数并将它们存储在variablesparams_1 .. params_n ,其中n = params_0 =数组的元素个数:

 @echo off rem Storing the program parameters into the array 'params': rem Delayed expansion is left disabled in order not to interpret "!" in program parameters' values; rem however, if a parameter is not quoted, special characters in it (like "^", "&", "|") get interpreted at program launch set /a count=0 :repeat set /a count+=1 set "params_%count%=%~1" shift if defined params_%count% ( goto :repeat ) else ( set /a count-=1 ) set /a params_0=count rem Printing the program parameters stored in the array 'params': rem After the variables params_1 .. params_n are set with the program parameters' values, delayed expansion can rem be enabled and "!" are not interpreted in the variables params_1 .. params_n values setlocal enabledelayedexpansion for /l %%i in (1,1,!params_0!) do ( echo params_%%i: "!params_%%i!" ) endlocal pause goto :eof 
 @echoclosures
 :开始

 ::在这里插入你的代码
回声。%% 1现在是:%〜1
 ::结束在这里插入你的代码

如果“%〜2”NEQ“”(
    转移
    转到:开始
 ) 

上面的很多信息让我有了进一步的研究,并最终得到了我的答案,所以我想贡献一下我所做的,希望能帮助别人:

  • 我也想将不同数量的variables传递给一个batch file,以便在文件中处理它们。

  • 我确定使用引号将它们传递给batch file

  • 我想他们处理类似于下面 – 但使用循环,而不是手动写出:

所以我想执行这个:

 prog_ZipDeleteFiles.bat "_appPath=C:\Services\Logs\PCAP" "_appFile=PCAP*.?" 

通过for循环的魔法在batch file中执行以下操作:

 set "_appPath=C:\Services\Logs\PCAP" set "_appFile=PCAP*.?" 

我遇到的问题是我所有使用for循环的尝试都不起作用。 下面的例子:

 for /f "tokens* delims= " in %%A (%*) DO ( set %%A ) 

只会做:

 set "_appPath=C:\Services\Logs\PCAP" 

并不是:

 set "_appPath=C:\Services\Logs\PCAP" set "_appFile=PCAP*.?" 

即使设置后

 SETLOCAL EnableDelayedExpansion 

原因是for循环读取整行并在循环的第一次迭代期间将第二个参数分配给%% B。 因为%*表示所有参数,所以只处理一行 – ergo只发生一次for循环。 这是事实certificate,我的逻辑是错误的。

所以我停止了尝试使用for循环,并通过使用if,shift和goto语句简化了我正在尝试做的事情。 同意它的一些黑客,但它更适合我的需求。 我可以遍历所有的参数,然后使用if语句将其全部处理掉。

我正在努力实现的赢得声明:

 echo on :processArguments :: Process all arguments in the order received if defined %1 then ( set %1 shift goto:processArguments ) ELSE ( echo off ) 

更新 – 我不得不修改到下面,而是试图引用%1和使用这种方式转移时暴露的所有环境variables:

 echo on shift :processArguments :: Process all arguments in the order received if defined %0 then ( set %0 shift goto:processArguments ) ELSE ( echo off ) 

Windows版本(需要socat虽然)

 C:\Program Files (x86)\Git\bin>type gitproxy.cmd socat STDIO PROXY:proxy.mycompany.de:%1:%2,proxyport=3128 

设置:

 C:\Users\exhau\AppData\Roaming\npm>git config --global core.gitproxy gitproxy.cmd 

您可以使用%1, %2等来访问命令行参数。 我不认为有一个variables,包含整个列表。 你可能会写一个简单的循环来决定传递了多less个参数。

编辑:显然有:)

对于需要从basepath拖尾反斜杠的人

 set source=%~dp0 ::Remove the trailing backslash from source IF %source:~-1%==\ SET source=%source:~0,-1% echo %source%