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

Get list of passed arguments in Windows batch script (.bat)

我想找到一个与bash的$@相对应的windows批处理,它包含了传递到脚本中的所有参数的列表。

或者我要麻烦shift


对于所有命令线参数(不包括脚本名称ITSELF),Dancavallaro has it right,EDOCX1&0.你也可能发现这些用处:

呼叫分组文件的命令(可以是foo..\fooc:\bats\foo.bat,等等)是第一指挥线参数是第二命令线参数因此,第九届会议之后,可以使用第八届会议(和第九届会议)的时间。

批量文件的实际名称,注意呼叫方法(一些批量)脚本的驱动与路径脚本的名称是否完全合格

More info examples at https://www.ss64.com/nt/syntax-args.html and https://www.robvanderwoude.com/parameters.html


看起来所有的论据都已转到脚本。


法国电力公司坚持论据,但这可能会使他们难以接近,因为内容会被解释。因此,不可能用正常的语句来处理类似的事情。

1
myBatch.bat"&"^&

每个线路故障,作为CMD.Exe尝试执行一个安培剂(1%的含量是EDOCX1〕〔16〕)

ZZU1

但有一个临时档案工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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%1rem之后扩展的。页:1但要能再现echo on的输出,你需要两个。

使用* #的特征是安全地对付/?等内容(将为REM提供帮助)。或者,一个关怀^在线上的结尾可以作为一个多线性特征。

The For/F should be working with delayed expansion off,else contents with"!"会被驱逐的当你在param1中重新定义了特级特性之后,你得到了它。

在安全的方式下,使延迟膨胀成为可能。

Edit:one remark to%0

包括呼叫分组的命令,也保存如EDOCX1&26但在呼唤%0之后,也在%~0中包含了该函数的名称(或更好的条纹被用来呼唤该函数)。但是,你仍然可以记住文件名。

1
2
3
4
5
6
7
8
@echo off
echo main %0, %~0, %~f0
call :myLabel+xyz
exit /b

:MYlabel
echo func %0, %~0, %~f0
exit /b

输出

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


我发现下次你需要看这些信息的时候如果你不打开一个浏览器和谷歌,你可以在你的CMD中找到它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...

%* 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 %*

The way to retrieve all the args to a script is here:

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


这是一个很简单的方法,可以获得阿尔格斯,把他们当作恩人。在这个例子中,我将把钥匙和价值一并提交给他们。

Save the following code example as"Args.bat."然后叫批量文件你拯救了一条指挥线Example:ARG.BAT-X-90-Y 120

我给你提供了一些回音命令,通过这个过程。但是End result is that--X will have a value of 90 and--Y will have a value of 120(that if you run the example as specified;-).

然后你可以使用条件声明来确定你的密码块在哪里或不在哪里。所以他们说跑"你好世界"然后我可以使用"如果定义-X回声%---X%"的语句,结果将是"你好世界"。如果你运行这个游泳池,它应该更明智。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@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


The following code simulates an array("EDOCX1&31")-takes the parameters received by the script and stores them in the variables params_1EDOCX1&34=EDOCX1&35>The number of elements of the array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@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

enter image description here

For to use looping get all arguments and in pure batch:

1
2
3
4
5
6
7
8
@echo off && setlocal EnableDelayedExpansion

 set"_cnt=0" && for %%Z in (%*) do (
 set"_arg_=%%Z" && set /a"_cnt=!_cnt! + 1" && set"_arg_[!_cnt!]=!_arg_!"
 shift && for /l %%l in (!_cnt! 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...

1
2
3
4
5
6
7
8
9
 @echo off && setlocal EnableDelayedExpansion

 set"_cnt=0" && for %%Z in (%*) do (
 set"_arg_=%%Z" && set /a"_cnt=!_cnt! + 1" && set"_arg_[!_cnt!]=!_arg_!"
 shift

 )

 run_command !_arg_[1]! !_arg_[2]! !_arg_[2]!> log.txt

如果引号中的参数包含空格,那么%*将无法正常工作。我找到的最佳解决方案是有一个连接所有参数的循环:https://serverfault.com/a/22541

1
2
3
4
5
6
7
8
9
10
set args=%1
shift
:start
if [%1] == [] goto done
set args=%args% %1
shift
goto start

:done
(use %args% here)

上面的很多信息引导我进一步研究,最终我的答案,所以我想贡献我最后所做的,希望它能帮助其他人:

  • 我还想将不同数量的变量传递给一个批处理文件,以便在该文件中处理它们。

  • 我可以用引号将它们传递到批处理文件中

  • 我希望它们的处理方式与下面类似-但使用循环而不是手动写出:

所以我想执行这个:

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

通过for循环的魔力,在批处理文件中执行此操作:

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

我遇到的问题是,我所有使用for循环的尝试都失败了。以下示例:

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

只会做:

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

而不是:

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

即使在设置之后

1
SETLOCAL EnableDelayedExpansion

原因是for循环读取整行,并在循环的第一次迭代期间将第二个参数分配给了%%b。因为%*表示所有参数,所以只需要处理一行—因此只会发生for循环的一次传递。事实证明,这是按设计的,我的逻辑是错误的。

所以我停止使用for循环,并通过使用if、shift和goto语句简化了我要做的事情。同意这是一个有点黑客,但它更适合我的需要。我可以循环使用所有参数,然后在处理完所有参数后使用if语句退出循环。

我努力实现的目标的致胜声明:

1
2
3
4
5
6
7
8
9
10
echo on
:processArguments
:: Process all arguments in the order received
if defined %1 then (
    set %1
    shift
    goto:processArguments
) ELSE (
    echo off
)

更新-我必须修改到下面的内容,当我试图引用%1并以这种方式使用shift时,我暴露了所有的环境变量:

1
2
3
4
5
6
7
8
9
10
11
echo on
shift
:processArguments
:: Process all arguments in the order received
if defined %0 then (
    set %0
    shift
    goto:processArguments
) ELSE (
    echo off
)


1
2
3
4
5
6
7
8
9
10
11
@echo off
:start

:: Insert your code here
echo.%%1 is now:%~1
:: End insert your code here

if"%~2" NEQ"" (
    shift
    goto :start
)


Windows Version(Needs Socat Though)

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

Setting it up:

1
2
3
C:\Users\exhau\AppData
oaming
pm>git config --global core.gitproxy gitproxy.cmd