我想找到一个Windows批处理对应Bash的$@,它持有传递到脚本的所有参数的列表。
还是要我费心去换班?
我想找到一个Windows批处理对应Bash的$@,它持有传递到脚本的所有参数的列表。
还是要我费心去换班?
当前回答
如果参数在包含空格的引号中,%*将无法正确工作。 我发现的最佳解决方案是使用一个连接所有参数的循环:https://serverfault.com/a/22541
set args=%1
shift
:start
if [%1] == [] goto done
set args=%args% %1
shift
goto start
:done
(use %args% here)
其他回答
%*似乎包含传递给脚本的所有参数。
Dancavallaro是正确的,%*用于所有命令行参数(不包括脚本名称本身)。你可能还会发现这些有用:
%0 -用于调用批处理文件的命令(可以是foo, ..\foo, c:\bats\foo.bat等) %1是第一个命令行参数, %2是第二个命令行参数, 等等,直到%9 (SHIFT可以用于9号之后的)。
%~nx0—批处理文件的实际名称,与调用方法无关(some-batch.bat) %~dp0 -脚本的驱动器和路径(d:\scripts) %~dpnx0 -是脚本的完全限定路径名(d:\scripts\some-batch.bat)
更多信息的例子在https://www.ss64.com/nt/syntax-args.html和https://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并展开%1(也适用于%2 ..% *)。 但是为了能够重定向echo on的输出,您需要两个for - loop。
额外的字符* #用于安全对抗/?(有助于快速眼动)。 或者行尾的插入符号^可以作为多行字符。
FOR /F应关闭延迟展开,否则包含“!”的内容将被销毁。 在删除param1中的额外字符后,您就得到了它。
要以安全的方式使用param1,请启用延迟扩展。
编辑:一条注释到%0
%0包含用于调用批处理的命令,也像FoO.BaT中一样保留大小写 但是在调用函数%0之后,也在%~0中包含函数名(或者更好的是用于调用函数的字符串)。 但是使用%~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
@echo off :start :: Insert your code here echo.%%1 is now:%~1 :: End insert your code here if "%~2" NEQ "" ( shift goto :start )
对于使用循环获取所有参数,并且是纯批处理:
注意事项:用于不带:?*&<>
@echo off && setlocal EnableDelayedExpansion
for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!")
:: write/test these arguments/parameters ::
for /l %%l in (1 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_!"
echo= !_arg_[1]! !_arg_[2]! !_arg_[2]!> log.txt