Batch file 使用ENABLEDELAYEDEXPANSION

Batch file 使用ENABLEDELAYEDEXPANSION,batch-file,cmd,Batch File,Cmd,在批处理脚本中使用ENABLEDELAYEDEXPANSION时,调用ENDLOCAL后,在批处理脚本中创建的变量是否仍然存在?我知道,您的问题基本上是关于SETLOCAL命令及其效果,而不管使用了ENABLEDELAYEDEXPANSION选项(或任何其他选项) 我的简短回答是:No,假设变量在进入SETLOCAL的范围之前不存在 我的较长答覆如下: 退出作用域(即到达ENDLOCAL)时,放弃对SETLOCAL作用域内变量所做的所有更改。这包括: 定义以前未定义的变量: @ECHO OFF

在批处理脚本中使用ENABLEDELAYEDEXPANSION时,调用ENDLOCAL后,在批处理脚本中创建的变量是否仍然存在?

我知道,您的问题基本上是关于
SETLOCAL
命令及其效果,而不管使用了
ENABLEDELAYEDEXPANSION
选项(或任何其他选项)

我的简短回答是:No,假设变量在进入
SETLOCAL
的范围之前不存在

我的较长答覆如下:

退出作用域(即到达
ENDLOCAL
)时,放弃对
SETLOCAL
作用域内变量所做的所有更改。这包括:

  • 定义以前未定义的变量:

    @ECHO OFF
    
    <nul SET /P q=1.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    SETLOCAL
    
    SET ttt=
    <nul SET /P q=2.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    ENDLOCAL
    
    <nul SET /P q=3.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    @ECHO OFF
    
    SET ttt=1
    <nul SET /P q=1.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    SETLOCAL
    
    SET ttt=
    <nul SET /P q=2.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    ENDLOCAL
    
    <nul SET /P q=3.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
  • 取消定义以前定义的变量:

    @ECHO OFF
    
    <nul SET /P q=1.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    SETLOCAL
    
    SET ttt=
    <nul SET /P q=2.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    ENDLOCAL
    
    <nul SET /P q=3.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    @ECHO OFF
    
    SET ttt=1
    <nul SET /P q=1.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    SETLOCAL
    
    SET ttt=
    <nul SET /P q=2.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
    ENDLOCAL
    
    <nul SET /P q=3.
    IF DEFINED ttt (ECHO defined) ELSE (ECHO undefined)
    
  • 更改变量的值:

    @ECHO OFF
    
    SET ttt=1
    ECHO 1.ttt=%ttt%
    
    SETLOCAL
    
    SET ttt=2
    ECHO 2.ttt=%ttt%
    
    ENDLOCAL
    
    ECHO 3.ttt=%ttt%
    
    这将产生以下输出:

    1.ttt=1
    2.ttt=2
    3.ttt=1
    
正如我在开始时所说,无论您是否将其与其他选项一起使用,上述内容都适用于
SETLOCAL

总之,我想说的是,可以在
SETLOCAL
的范围内保存计算的结果,以便在
ENDLOCAL
之后使用。这里有一个小技巧可以让它成为可能:

…
ENDLOCAL & SET var=%var%
…
在分析此行时,
SETLOCAL
命令仍然有效,因此
%var%
将计算为最近存储到
var
中的值。当执行该行时,
var
变量在
ENDLOCAL
之后立即丢失其值,但是SET命令已经包含了它的值,只是被替换了,因此
var
将它接收回来,这让每个人都很满意

根据@Jeremy Murray的评论,如果包含
ENDLOCAL
和读取括号中单个块中变量的命令,您还可以访问
ENDLOCAL
之后的更改值:

…
(
ENDLOCAL
SET var=%var%
anything else
)
…
…
(
端部
设置变量=%var%
别的
)
…

效果是一样的,因为括号内的命令都是作为单个单元解析和执行的:首先解析所有命令,然后执行所有命令。

如果需要,还可以将endlocal放在paren语句中以执行多个集合。[请想象一下本例中的换行符:)](ENDLOCAL如果不是“%RETURN\u SIG%”则==“SET”签名=%RETURN\u SIG%”如果“%RETURN\u SIG%”则==“SET”签名=%DEFAULT\u SIG%”@Jeremy Murray:绝对正确。在执行第一个括号内的命令之前,将对所有命令进行分析。所以这和他们在同一条线上的效果是一样的。谢谢你指出这一点!我认为enabledelayedexpansion只能在调用SETLOCAL时使用?@Mechaflash:这是我被告知的,是的。但是要在endlocal之后保留任何可能的内容,它要复杂得多,因为类似于
you&me说的“me&you”
会因
set var=%var%
变量而失败