简体   繁体   English

达到最大setlocal递归级别 - setlocal

[英]Maximum setlocal recursion level reached - setlocal

Read a few bits, but struggling to get my head around this. 阅读几点,但努力想要了解这一点。 Basically, having to use Setlocal with enable and disable delayed expansion to use and manipulate variables with exclamation marks in. Example of this code below. 基本上,必须使用Setlocal启用和禁用延迟扩展来使用和操作带有感叹号的变量。下面的代码示例。 The code section can be cycled through many times in a session, and at some point (I believe it's 32?) I get a "Maximum setlocal recursion level reached" error. 代码部分可以在一个会话中循环多次,并且在某些时候(我相信它是32?)我得到“达到最大setlocal递归级别”错误。

I've read a little about Endlocal, but can't get my head around how to use it. 我已经阅读了一些关于Endlocal的内容,但无法理解如何使用它。 My worry is that some parts of the code extract (below) use environment vars from the surrounding code (eg %_emuExts%) whilst there are some vars set in the extract that I want to use outside the extract (eg %launchfile% and %lauchfile2%). 我担心的是代码提取的某些部分(下面)使用来自周围代码的环境变量(例如%_emuExts%),而在提取中设置了一些我想在提取之外使用的变量(例如%launchfile%和%) lauchfile2%)。 Hope that makes some kinda sense! 希望有一点意义!

My question is really around where to put any EndLocal to ensure that can use variables from 'around' the code and also set variables that can be used outside of the 'local' bit. 我的问题是在哪里放置任何EndLocal以确保可以使用代码“周围”的变量,还可以设置可以在“本地”位之外使用的变量。 To be honest - struggling to conceptualize the ideas around 'local' and 'recursion levels' 说实话 - 努力概念化“本地”和“递归级别”的想法

The code: 代码:

:: 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....

Functionally, this cycles through the present dir via the extentions specified in %_emuExts% and sets %launchfile% to the 'priority' file extension (rightmost extension). 在功能上,它通过%_emuExts%中指定的扩展来循环显示当前目录,并将%launchfile%设置为'priority'文件扩展名(最右边的扩展名)。 Some filenames have exclamation marks in - hence the delayed expansion switching. 一些文件名中包含感叹号 - 因此延迟扩展切换。 It then switches out "!" 然后切换出“!” for "{-exc-}" 为“{-exc-}”

Apologies - may be obvious to you guys - but hard to get head round. 道歉 - 对你们来说可能是显而易见的 - 但很难让人头脑发热。 Thanks 谢谢

Rather than complicating the code with all the SETLOCALs, can the code be modified so that you don't need to to enable delayed expansion? 而不是使代码与所有SETLOCAL复杂化,代码是否可以修改,以便您不需要启用延迟扩展? I don't see any code above that requires it. 我没有看到上面的任何代码需要它。 Granted there is code missing. 当然,缺少代码。 Maybe we should look at that. 也许我们应该看一下。 If you must SETLOCAL numerous times,there is a technique called 'tunneling' that allows you to pass variables that are local in one section of code to another section of code. 如果你必须多次SETLOCAL,有一种称为“隧道”的技术,它允许你将一段代码中的本地变量传递给另一段代码。 To do that you can do something like this endlocal & set MyVar=%MyVar% . 要做到这一点,你可以做这样的endlocal & set MyVar=%MyVar% This works because at load time the entire line is parsed and %MyVar% is expanded. 这是有效的,因为在加载时解析整行,并扩展%MyVar%。 The run time behavior is to then set that value into a new variable (of same or different name, as you choose) outside the localized code. 运行时行为是将该值设置为本地化代码之外的新变量(具有相同或不同名称,如您所选)。

To manage exclamation marks in file names use a procedure call as in next example. 要管理文件名中的感叹号,请使用过程调用,如下例所示。 Note setlocal and endlocal are like some kind of parentheses so should be always coupled together. 注意setlocalendlocal就像某种括号,所以应该总是耦合在一起。 Doing that you never reach the maximum setlocal recursion level... 这样做你永远不会达到最大的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

Thanks fellas! 谢谢fellas! I'm an amateur, so my solution probably not the most eloquent, but it worked! 我是一个业余爱好者,所以我的解决方案可能不是最有说服力的,但它确实有效! The majority of my script runs with setlocalexpantion enabled. 我的大部分脚本都在启用setlocalexpantion的情况下运行。 A few things helped solve this: 一些事情有助于解决这个问题:

  • Treating setlocal + endlocal as 'parentheses' - closing any setlocal with matching endlocal 将setlocal + endlocal视为'括号' - 关闭任何匹配endlocal的setlocal
  • If needing to 'pass' a variable set 'within' these paretheses to the rest of the script, using the endlocal with the tunnelling method 如果需要将这些paretheses中的变量集“传递”到脚本的其余部分,则使用带有隧道方法的endlocal
  • Finding that if you endlocal, the script returns to the previous 'setlocal' state (ie no need to re-enable delayed expansion via set following 'closed' disable) 发现如果你是endlocal,脚本将返回到之前的'setlocal'状态(即不需要通过在'closed'禁用后设置重新启用延迟扩展)

So, final, working code: 最后,工作代码:

:: 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....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM