达到最大setlocal递归级别 - setlocal

时间:2014-12-10 20:01:44

标签: batch-file recursion

阅读几点,但努力想要理解这一点。基本上,必须使用Setlocal启用和禁用延迟扩展来使用和操作带有感叹号的变量。下面的代码示例。代码部分可以在一个会话中循环多次,并且在某些时候(我相信它是32?)我得到了一个"达到的最大setlocal递归级别"错误。

我已经阅读了一些关于Endlocal的内容,但无法理解如何使用它。我担心的是代码提取的某些部分(下面)使用来自周围代码的环境变量(例如%_emuExts%),而在提取中设置了一些我想在提取之外使用的变量(例如%launchfile%和%) lauchfile2%)。希望有点意义!

我的问题实际上是在哪里放置任何EndLocal以确保可以使用来自'周围的变量。代码并设置可以在本地'之外使用的变量。位。说实话 - 努力概念化本地'周围的想法。和'递归级别'

代码:

:: Example of var contents:
set _emuExts=cue bin iso
:: Problem code:
Setlocal DisableDelayedExpansion
for %%e in (%_emuExts%) do (
        echo Extention: %%e 
        for /F "delims=" %%a in ('dir /b *.%%e') do (               
                set launchfile=%%~na.%%e            
                echo Launchfile this iteration: [%%~na.%%e]%_log1%
            )
        echo Next iteration......
    )
echo Final Launchfile: "%launchfile%" %_log1%
set launchfile2=%launchfile:!={-exc-}%
echo Launchfile with replace: %launchfile2%%_log1%
setlocal enabledelayedexpansion
:: .....more code   
Setlocal DisableDelayedExpansion
set "_FinalemuCmd=%_FinalemuCmd:{-exc-}=!%"
start /wait "" "%_emuExe%" %_FinalemuCmd%
setlocal enabledelayedexpansion
:: ...continues....

在功能上,它通过%_emuExts%中指定的扩展来循环显示当前目录,并将%launchfile%设置为' priority'文件扩展名(最右边的扩展名)。一些文件名中包含感叹号 - 因此延迟扩展切换。然后它会切换出来"!" for" { - exc - }"

道歉 - 对你们来说可能是显而易见的 - 但很难让人满意。感谢

3 个答案:

答案 0 :(得分:1)

是否可以修改代码以使您不需要启用延迟扩展,而不是使代码与所有SETLOCAL复杂化?我上面没有看到任何需要它的代码。当然,缺少代码。也许我们应该看一下。如果你必须多次SETLOCAL,有一种叫做“隧道”的技术。这允许您将一段代码中的本地变量传递给另一段代码。要做到这一点,你可以做这样的事情endlocal & set MyVar=%MyVar%。这是有效的,因为在加载时解析整行,并扩展%MyVar%。运行时行为然后将该值设置为本地化代码之外的新变量(具有相同或不同名称,如您所选)。

答案 1 :(得分:1)

要管理文件名中的感叹号,请使用过程调用,如下例所示。注意setlocalendlocal就像某种括号,因此应始终将它们连接在一起。这样做你永远不会达到最大的setlocal递归级别......

@echo off
@SETLOCAL enableextensions enabledelayedexpansion
  set "launchfile="
  for /f %%G in ('dir /b *.enu') do (
    SETLOCAL disabledelayedexpansion
      Call :exclamsub "%%~dpnxG"
    ENDLOCAL
  )
@ENDLOCAL
goto :eof

:exclamsub
@echo off
  set "launchfile=%~1"
  @echo %1 ^[%launchfile%^]
goto :eof

答案 2 :(得分:1)

谢谢你!我是业余爱好者,所以我的解决方案可能不是最有说服力的,但它确实有效!我的大部分脚本都在启用setlocalexpantion的情况下运行。一些事情有助于解决这个问题:

  • 将setlocal + endlocal视为'括号' - 关闭任何匹配endlocal的setlocal
  • 如果需要通过'一个变量集'在'使用带有隧道方法的endlocal
  • ,这些对剧本其余部分的重要性
  • 发现如果你是endlocal,那么脚本将返回到之前的“setlocal”。状态(即无需通过设置跟随'关闭'禁用)重新启用延迟扩展

所以,最后的工作代码:

:: Example of var contents:
set _emuExts=cue bin iso
:: Problem code:
Setlocal DisableDelayedExpansion
for %%e in (%_emuExts%) do (
        echo Extention: %%e 
        for /F "delims=" %%a in ('dir /b *.%%e') do (               
                set launchfile=%%~na.%%e
                echo Launchfile this iteration: [%%~na.%%e]%_log1%
            )
        echo Next iteration......
    )
echo Final Launchfile: "%launchfile%" %_log1%
set launchfile2=%launchfile:!={-exc-}%
echo Launchfile with replace: %launchfile2%%_log1%
endlocal & (
        set "launchfile=%launchfile%"
        set "launchfile2=%launchfile2%"
    )
:: .....more code  
Setlocal DisableDelayedExpansion
set "_FinalemuCmd=%_FinalemuCmd:{-exc-}=!%"
echo after replace and no delayed: %_FinalemuCmd%%_log1%
pause
echo 
start /wait "" "%_emuExe%" %_FinalemuCmd%
::ping -n 3 localhost  > nul
endlocal
:: ...continues....