在批处理中在endlocal之后保持变量

时间:2019-06-21 11:34:31

标签: windows batch-file cmd delayedvariableexpansion

我有一个文件夹结构,例如C:\ Temp \,并且有很多文件夹和文件,并且在每个文件夹中都有一个“ callme.bat”。我想创建一个所谓的main.bat,它一个接一个地调用main'窗口中的callme文件。但是有一个问题,在callme文件中有一些包含“!”的回显。标记是什么对我造成了问题。

我意识到setlocal-endlocal组合的问题,因为批处理凭条想解释“!”中的消息。标记,所以我必须使用endlocal,但是如果不这样做,我将无法运行音素蝙蝠。

callme.bat

@echo off
echo !!! hidden message !!! not hidden message
pause

main.bat变体1

@echo off
setlocal enabledelayedexpansion

set PATH=C:\Temp
for /F %%x in ('dir /B/A:D %PATH%') do (
    set CURR_DIR=%PATH%\%%x
    set ACTUAL_BATCH=!CURR_DIR!\callme.bat
    echo !ACTUAL_BATCH!

    call !ACTUAL_BATCH!
    pause
)
pause
exit

main.bat变体2

@echo off
set PATH=C:\Temp
for /F %%x in ('dir /B/A:D %PATH%') do (
    setlocal enabledelayedexpansion

    set CURR_DIR=%PATH%\%%x
    set ACTUAL_BATCH=!CURR_DIR!\callme.bat
    echo !ACTUAL_BATCH!

    ENDLOCAL & SET VAR=!ACTUAL_BATCH!
    echo %VAR%
    pause
)
pause
exit

main.bat变体3

@echo off
set PATH=C:\Temp
for /F %%x in ('dir /B/A:D %PATH%') do (
    setlocal enabledelayedexpansion

    set CURR_DIR=%PATH%\%%x
    set ACTUAL_BATCH=!CURR_DIR!\callme.bat
    echo !ACTUAL_BATCH!

    REM source: https://stackoverflow.com/questions/3262287/make-an-environment-variable-survive-endlocal
    for /f "delims=" %%A in (""!ACTUAL_BATCH!"") do endlocal & set "VAR=%%~A"
    echo %VAR%

    call %VAR%
    pause
)
pause
exit

所以我不知道该怎么办。有人有主意吗?

变体1的输出:

C:\Temp\1\callme.bat
 not hidden message
C:\Temp\2\callme.bat
 not hidden message

变体2-3的输出:

C:\Temp\1\callme.bat
ECHO is off.
C:\Temp\2\callme.bat
ECHO is off.

2 个答案:

答案 0 :(得分:2)

关于您的代码的一些要点:

  1. 切勿使用PATH作为变量名,因为它会破坏PATH变量以搜索可执行文件。

  2. 使用扩展的SET语法set "varname=content"来避免训练空间问题。

  3. 您只需使用setlocal DisableDelayedExpansion

  4. 来禁用延迟扩展模式
@echo off
setlocal EnableDelayedExpansion

set MY_PATH=C:\Temp
for /F %%x in ('dir /B/A:D %PATH%') do (
    set "CURR_DIR=%MY_PATH%\%%x"
    set "ACTUAL_BATCH=!CURR_DIR!\callme.bat"

    call :execute ACTUAL_BATCH
    pause
)
pause
exit /b

:execute ACTUAL_BATCH
set "batFile=!%~1!"
echo Calling !batFile!

setlocal DisableDelayedExpansion
call %batFile%
endlocal

exit /b

答案 1 :(得分:0)

TL; DR

ENDLOCAL&set "varname=%sourcevarname%"

可能是,其中varname是要设置的变量名,而sourcevarname是要为其值分配给varname的变量-它们 CAN 是相同的名称,即使该语句在逻辑上看起来为空-它也在setlocal/endlocal块中导出变量。

关键点:必须位于同一条物理线上,如有必要可以重复(例如

 ENDLOCAL&set "varname=%sourcevarname%"&set "varname2=%sourcevarname2%"

所以

 ENDLOCAL&set "fred=%fred%"&set "bill=%george%"

完全有效,可以将setlocal / endlocal括号之外的fred的值设置为内部的最终值,并将bill外部的值设置为george的内部值。