获取 Windows 批处理脚本 (.bat) 中传递的参数列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/357315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get list of passed arguments in Windows batch script (.bat)
提问by wheleph
I'd like to find a Windows batch counterpart to Bash's $@
that holds a list of all arguments passed into a script.
我想找到 Bash 的 Windows 批处理对应物,$@
其中包含传递给脚本的所有参数的列表。
Or I have to bother with shift
?
还是我要费心shift
?
回答by matt wilkie
dancavallarohas it right, %*
for all command line parameters (excluding the script name itself). You might also find these useful:
%*
对于所有命令行参数(不包括脚本名称本身),dancavallaro是正确的。这些对你也可能有用:
%0
- the command used to call the batch file (could be foo
, ..\foo
, c:\bats\foo.bat
, etc.)%1
is the first command line parameter,%2
is the second command line parameter,
and so on till %9
(and SHIFT
can be used for those after the 9th).
%0
- 用于调用批处理文件的命令(可以是foo
、..\foo
、c:\bats\foo.bat
等)%1
是第一个命令行参数,%2
是第二个命令行参数,
依此类推%9
(SHIFT
可以用于第 9 个之后的)。
%~nx0
- the actual name of the batch file, regardless of calling method (some-batch.bat)%~dp0
- drive and path to the script (d:\scripts)%~dpnx0
- is the fully qualified path name of the script (d:\scripts\some-batch.bat)
%~nx0
- 批处理文件的实际名称,与调用方法无关 (some-batch.bat) %~dp0
- 驱动器和脚本路径 (d:\scripts) %~dpnx0
- 是脚本的完全限定路径名 (d:\scripts\some -batch.bat)
More info examples at https://www.ss64.com/nt/syntax-args.htmland https://www.robvanderwoude.com/parameters.html
更多信息示例见https://www.ss64.com/nt/syntax-args.html和https://www.robvanderwoude.com/parameters.html
回答by dancavallaro
%*
seems to hold all of the arguments passed to the script.
%*
似乎保存了传递给脚本的所有参数。
回答by jeb
%1
... %n
and %*
holds the arguments, but it can be tricky to access them, because the content will be interpreted.
Therefore it is impossible to handle something like this with normal statements
%1
...%n
并%*
保存参数,但访问它们可能很棘手,因为内容将被解释。
因此,用普通语句处理这样的事情是不可能的
myBatch.bat "&"^&
Each line fails, as cmd.exe try to execute one of the ampersands (the content of %1 is "&"&
)
每一行都失败,因为 cmd.exe 尝试执行其中一个与号(%1 的内容是"&"&
)
set var=%1
set "var=%1"
set var=%~1
set "var=%~1"
But there exists a workaround with a temporary file
但是存在一个临时文件的解决方法
@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!'
The trick is to enable echo on
and expand the %1
after a rem
statement (works also with %2 .. %*).
But to be able to redirect the output of echo on
, you need the two FOR-LOOPS.
关键是要实现echo on
和扩大%1
一个后rem
声明(也可与2%..%*)。
但是为了能够重定向 的输出echo on
,您需要两个 FOR 循环。
The extra characters * #
are used to be safe against contents like /?
(would show the help for REM).
Or a caret ^ at the line end could work as a multiline character.
额外的字符* #
用于保护诸如/?
(将显示 REM 的帮助)之类的内容。
或者行尾的插入符号 ^ 可以用作多行字符。
The FOR /F should be work with delayed expansion off, else contents with "!" would be destroyed.
After removing the extra characters in param1
and you got it.
FOR /F 应该在延迟扩展关闭的情况下工作,否则内容为“!” 会被摧毁。
删除多余的字符后param1
,你就明白了。
And to use param1
in a safe way, enable the delayed expansion.
并且为了param1
安全使用,启用延迟扩展。
Edit: One remark to %0
编辑:对 %0 的一个评论
%0
contains the command used to call the batch, also preserving the case like in FoO.BaT
But after a call to a function %0
and also in %~0
contains the function name (or better the string that was used to call the function).
But with %~f0
you still can recall the filename.
%0
包含用于调用批处理的命令,也保留像 in FoO.BaT
But 在调用函数之后的大小写,%0
并且还%~0
包含函数名称(或者更好的是用于调用函数的字符串)。
但是%~f0
你仍然可以回忆起文件名。
@echo off
echo main %0, %~0, %~f0
call :myLabel+xyz
exit /b
:MYlabel
echo func %0, %~0, %~f0
exit /b
Output
输出
main test.bat, test.bat, C:\temp\test.bat
func :myLabel+xyz, :myLabel+xyz, C:\temp\test.bat
回答by KFL
I found that next time when you need to look up these information. Instead of opening a browser and google it, you could just type call /?
in your cmd and you'll get it:
我发现下次需要查找这些信息时。无需打开浏览器并在 google 上搜索它,您只需输入call /?
cmd 即可获得:
...
%* in a batch script refers to all the arguments (e.g. %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 %*
回答by djangofan
The way to retrieve all the args to a script is here:
将所有参数检索到脚本的方法在这里:
@ECHO off
ECHO The %~nx0 script args are...
for %%I IN (%*) DO ECHO %%I
pause
回答by djangofan
Here is a fairly simple way to get the args and set them as env vars. In this example I will just refer to them as Keys and Values.
这是获取 args 并将它们设置为 env vars 的一种相当简单的方法。在这个例子中,我将它们称为键和值。
Save the following code example as "args.bat". Then call the batch file you saved from a command line. example: arg.bat --x 90 --y 120
将以下代码示例另存为“args.bat”。然后从命令行调用您保存的批处理文件。示例:arg.bat --x 90 --y 120
I have provided some echo commands to step you through the process. But the end result is that --x will have a value of 90 and --y will have a value of 120(that is if you run the example as specified above ;-) ).
我提供了一些 echo 命令来引导您完成整个过程。但最终结果是 --x 的值为 90, --y 的值为 120(也就是说,如果您按照上面指定的方式运行示例 ;-) )。
You can then use the 'if defined' conditional statement to determine whether or not to run your code block. So lets say run: "arg.bat --x hello-world" I could then use the statement "IF DEFINED --x echo %--x%" and the results would be "hello-world". It should make more sense if you run the batch.
然后,您可以使用“if defined”条件语句来确定是否运行您的代码块。所以让我们说运行:“arg.bat --x hello-world”然后我可以使用语句“IF DEFINED --x echo %--x%”,结果将是“hello-world”。如果您运行批处理,它应该更有意义。
@setlocal enableextensions enabledelayedexpansion
@ECHO off
ECHO.
ECHO :::::::::::::::::::::::::: arg.bat example :::::::::::::::::::::::::::::::
ECHO :: By: User2631477, 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 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 i.e. %~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
回答by It Wasn't Me
For to use looping to get all arguments and in pure batch:
For 使用循环获取所有参数和纯批处理:
Obs:For using without: ?*&<>
Obs:用于不使用:?*&<>
@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
Your code is ready to do something with the argument number where it needs, like...
您的代码已准备好在需要的地方使用参数编号执行某些操作,例如...
@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
回答by It Wasn't Me
The following code simulates an array ('params
') - takes the parameters received by the script and stores them in the variables params_1
.. params_n
, where n
=params_0
=the number of elements of the array:
以下代码模拟了一个数组 (' params
') - 获取脚本接收到的参数并将它们存储在变量params_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
回答by scientist_7
You can use For
Commad,to get list of Arg.
您可以使用For
命令来获取 Arg 列表。
Help : For /?
Help : Setlocal /?
帮助:For /?
帮助:Setlocal /?
Here is my way =
这是我的方式=
@echo off
::For Run Use This = cmd /c ""Args.cmd" Hello USER Scientist etc"
setlocal EnableDelayedExpansion
set /a Count=0
for %%I IN (%*) DO (
Echo Arg_!Count! = %%I
set /a Count+=1
)
Echo Count Of Args = !Count!
Endlocal
Do not need Shift command.
不需要 Shift 命令。
回答by Speedstone
If you have parameters in quotes that containing spaces, %*
will not work correctly.
The best solution I found is to have a loop that joins all arguments: https://serverfault.com/a/22541
如果引号中包含空格的参数%*
将无法正常工作。我发现的最好的解决方案是有一个循环加入所有参数: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)