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 

编辑:这里使用的“技巧”涉及:

  1. 在每个循环迭代中,使用包含百分号字符( %% )和计数器variablesarg_idx的string构造表示当前计算的命令行参数variables(即“%1”,“%2”等)的string。

  2. 将该string存储到variablescurr_arg_label

  3. 将该string( !curr_arg_label! )和返回variables的名称( curr_arg_value )传递给原始子程序get_value

  4. 在子程序中,第一个参数的( %1 )值用于赋值( set )的左侧,右侧用于第二个参数的( %2 )值。 但是,当第二个子程序的参数被传递时,通过命令解释器将其parsing为主程序的命令行参数的值。 也就是说,传递的内容不是例如“%4”,而是第四个命令行参数variables保存的值(示例用法中的“another_arg”)。

  5. 然后,给予子程序的variables作为返回variables( curr_arg_value )被testing为未定义的,如果当前评估的命令行参数不存在,则会发生这种情况。 最初,这是将方括号中包含的返回variables的值与空方括号(这是我知道的可能包含引号的testing程序或子程序参数的唯一方法,并且是从试错阶段遗漏的剩余部分)的比较,但是从那时起就被固定下来了。