0

我正在尝试编写“引导程序”脚本来解析并将参数传递到我框架中的其他应用程序中。下面这个最小的、可重现的例子,实际应用要复杂得多

该脚本的基本语法是

bootstrapper.bat type command "foo=1" "bar=test2" "baz=true"

它应该调用

type/command.bat 1 test2 true

有问题的片段是这个嵌套的 for 循环:

setlocal enabledelayedexpansion

rem this is actually fetched elsewhere in live app
set procedure_arguments_count=3

set arguments=
for /L %%L in (1,1,!procedure_arguments_count!) do (
    for /f "tokens=1,2 delims==" %%a in ("%~3") do set arguments=!arguments! %%b
    shift /3
)

echo !arguments!

问题是arguments等于1 1 1而不是1 test2 true在执行此循环之后。

我相信内部循环预先填充了%~3设置为foo=1并忽略了 shift 命令。我无法更改shift,因为我需要支持 9 个以上的参数,也无法删除外循环(出于其他原因)。

问题是 - 我可以延迟扩展脚本参数吗?

4

2 回答 2

4

您的问题是,即使循环执行之前,%x参数也会被解析器替换为初始值,因此在循环内没有(立即)影响。forshiftfor

一个简单的解决方法:将参数 3....n 分配给一个变量并处理:

setlocal enabledelayedexpansion
for /f "usebackq tokens=2,*" %%i in ('%*') do (
  for %%k in (%%j) do (
    for /f "tokens=2 delims==" %%a in ("%%~k") do (
      set "args=!args! %%~a"
    )
  )
)
set args

第一个为for您获取参数 3...
第二个for处理您剩余的每个参数
第三个for从每个var=value字符串中获取值。

于 2019-09-14T18:26:43.880 回答
3
@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion

rem this is actually fetched elsewhere in live app
set procedure_arguments_count=3
set arguments=
for /L %%L in (1,1,!procedure_arguments_count!) do (
    call set "aux=%%~3"
    for /f "tokens=1,2 delims==" %%a in ("!aux!") do set arguments=!arguments! %%b
    shift /3
)
echo !arguments!

或没有FOR /L外环

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion

set "procedure_arguments_count=3"
set "arguments="
set "ii=%procedure_arguments_count%"

:loopfor
  if [%3]==[]   goto :done
  if %ii% EQU 0 goto :done
  for /f "tokens=1,2 delims==" %%a in ("%~3") do set arguments=%arguments% %%b
  SHIFT /3
  set /A ii-=1
  goto :loopfor
:done

echo(%arguments%
于 2019-09-14T18:36:51.140 回答