batch file – 命令行参数的数量
只是将一些shell脚本转换成batch file,有一件事我似乎无法find…这是一个简单的计数的命令行参数。
例如。 如果你有:
myapp foo bar
壳牌:
- $# – > 2
- $ * – > foo吧
- $ 0 – > myapp
- $ 1 – > foo
- $ 2 – >吧
批量
- ?? – > 2 <—-什么命令?
- %* – > foo吧
- %0 – > myapp
- %1 – > foo
- %2 – >吧
所以我环顾四周,要么我看错了位置,要么我是盲目的,但我似乎无法find一个方法来获得通过的命令行参数的数量。
是否有类似于batch file的命令“$#”的命令?
PS。 我发现的最接近的是遍历%1s并使用'shift',但是我需要在脚本中引用%1,%2等,所以这没有用。
谷歌search一下给你从Wikibooks以下结果:
set argC=0 for %%x in (%*) do Set /A argC+=1 echo %argC%
好像cmd.exe已经从旧的DOS天进化了一下:)
你倾向于用这种逻辑处理一些参数:
IF "%1"=="" GOTO HAVE_0 IF "%2"=="" GOTO HAVE_1 IF "%3"=="" GOTO HAVE_2
等等
如果你有超过9个参数,那么你就是用这种方法搞砸了。 有各种各样的黑客来创build计数器,你可以在这里find,但要警惕这些不是为了那些胆小的人。
函数:getargc
下面可能是你正在寻找。
@echo off setlocal enableextensions enabledelayedexpansion call :getargc argc %* echo Count is %argc% echo Args are %* endlocal goto :eof :getargc set getargc_v0=%1 set /a "%getargc_v0% = 0" :getargc_l0 if not x%2x==xx ( shift set /a "%getargc_v0% = %getargc_v0% + 1" goto :getargc_l0 ) set getargc_v0= goto :eof
它基本上遍历列表(这是本地的function,所以class次不会影响主程序中的列表),对它们进行计数,直到它用完。
它也使用一个漂亮的技巧,传递函数设置的返回variables的名称。
主程序只是说明如何调用它,然后回应这些论据,以确保它们不被触及:
C:\Here> xx.cmd 1 2 3 4 5 Count is 5 Args are 1 2 3 4 5 C:\Here> xx.cmd 1 2 3 4 5 6 7 8 9 10 11 Count is 11 Args are 1 2 3 4 5 6 7 8 9 10 11 C:\Here> xx.cmd 1 Count is 1 Args are 1 C:\Here> xx.cmd Count is 0 Args are C:\Here> xx.cmd 1 2 "3 4 5" Count is 3 Args are 1 2 "3 4 5"
尝试这个:
SET /A ARGS_COUNT=0 FOR %%A in (%*) DO SET /A ARGS_COUNT+=1 ECHO %ARGS_COUNT%
如果参数的数量应该是一个确切的数字(小于或等于9),那么这是一个简单的方法来检查它:
if "%2" == "" goto args_count_wrong if "%3" == "" goto args_count_ok :args_count_wrong echo I need exactly two command line arguments exit /b 1 :args_count_ok
避免使用任何一个shift
或一个for
循环的大小和可读性的代价。
@echo off setlocal EnableExtensions EnableDelayedExpansion set /a arg_idx=1 set "curr_arg_value=" :loop1 if !arg_idx! GTR 9 goto :done set curr_arg_label=%%!arg_idx! call :get_value curr_arg_value !curr_arg_label! if defined curr_arg_value ( echo/!curr_arg_label!: !curr_arg_value! set /a arg_idx+=1 goto :loop1 ) :done set /a cnt=!arg_idx!-1 echo/argument count: !cnt! endlocal goto :eof :get_value ( set %1=%2 )
输出:
count_cmdline_args.bat testing more_testing arg3 another_arg %1: testing %2: more_testing %3: arg3 %4: another_arg argument count: 4
编辑:这里使用的“技巧”涉及:
-
在每个循环迭代中,使用包含百分号字符(
%%
)和计数器variablesarg_idx
的string构造表示当前计算的命令行参数variables(即“%1”,“%2”等)的string。 -
将该string存储到variables
curr_arg_label
。 -
将该string(
!curr_arg_label!
)和返回variables的名称(curr_arg_value
)传递给原始子程序get_value
。 -
在子程序中,第一个参数的(
%1
)值用于赋值(set
)的左侧,右侧用于第二个参数的(%2
)值。 但是,当第二个子程序的参数被传递时,通过命令解释器将其parsing为主程序的命令行参数的值。 也就是说,传递的内容不是例如“%4”,而是第四个命令行参数variables保存的值(示例用法中的“another_arg”)。 -
然后,给予子程序的variables作为返回variables(
curr_arg_value
)被testing为未定义的,如果当前评估的命令行参数不存在,则会发生这种情况。 最初,这是将方括号中包含的返回variables的值与空方括号(这是我知道的可能包含引号的testing程序或子程序参数的唯一方法,并且是从试错阶段遗漏的剩余部分)的比较,但是从那时起就被固定下来了。