SETLOCAL 和 ENABLEDELAYEDEXPANSION 如何工作?
我注意到在大多数脚本中,两者通常位于同一行,如下所示:
SETLOCAL ENABLEDELAYEDEXPANSION
这两个实际上是单独的命令并且可以写在单独的行上吗?
如果设置 ENABLEDELAYEDEXPANSION
是在脚本的第一行设置并且直到脚本末尾才禁用,是否会对脚本产生不利影响?
I notice in most scripts, the two are usually in the same line as so:
SETLOCAL ENABLEDELAYEDEXPANSION
Are the two in fact separate commands and can be written on separate lines?
Will setting ENABLEDELAYEDEXPANSION
have an adverse effect on a script if it is set on the first lines of the script and not disabled until the end of the script?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我想你应该明白什么是延迟扩展。现有的答案并不能(充分)解释它。恕我直言。
输入
SET /?
很好地解释了这一点:另一个示例是此批处理文件:
这会打印
x2
和y2
:每个 1 都会被 2 替换。没有
setlocalenabledelayedexpansion
,感叹号就是这样,所以它会回显!b:1=2!
两次。由于读取(块)语句时会扩展普通环境变量,因此扩展
%b:1=2%
使用b
之前的值循环:z2
(但未设置时y2
)。I think you should understand what delayed expansion is. The existing answers don't explain it (sufficiently) IMHO.
Typing
SET /?
explains the thing reasonably well:Another example is this batch file:
This prints
x2
andy2
: every 1 gets replaced by a 2.Without
setlocal enabledelayedexpansion
, exclamation marks are just that, so it will echo!b:1=2!
twice.Because normal environment variables are expanded when a (block) statement is read, expanding
%b:1=2%
uses the valueb
has before the loop:z2
(buty2
when not set).ENABLEDELAYEDEXPANSION
是传递给SETLOCAL
命令的参数(查看setlocal /?
),它的效果在脚本的持续时间内有效,或者 <代码>ENDLOCAL:
特别是,这意味着如果您在脚本中使用
SETLOCAL ENABLEDELAYEDEXPANSION
,任何环境变量更改都会在结束时丢失,除非您采取特殊措施。ENABLEDELAYEDEXPANSION
is a parameter passed to theSETLOCAL
command (look atsetlocal /?
)Its effect lives for the duration of the script, or an
ENDLOCAL
:In particular, this means that if you use
SETLOCAL ENABLEDELAYEDEXPANSION
in a script, any environment variable changes are lost at the end of it unless you take special measures.ENABLEDELAYEDEXPANSION 部分在某些使用延迟扩展的程序中是必需的,即通过将变量名称括在感叹号中来获取在 IF 或 FOR 命令内修改的变量的值。
如果您在不需要此扩展的脚本中启用此扩展,则仅当脚本包含用感叹号 !LIKE! 括起来的名称时,该脚本的行为才会有所不同。 !这些!。通常名称只是被删除,但如果偶然存在同名变量,则结果是不可预测的,并且取决于该变量的值及其出现的位置。
SETLOCAL 部分在少数专用(递归)程序中是必需的,但当您希望确保不会偶然修改任何具有相同名称的现有变量,或者如果您想自动删除程序中使用的所有变量时,通常会使用 SETLOCAL 部分。程序。但是,由于没有单独的命令来启用延迟扩展,因此需要此功能的程序还必须包含 SETLOCAL 部分。
The ENABLEDELAYEDEXPANSION part is REQUIRED in certain programs that use delayed expansion, that is, that takes the value of variables that were modified inside IF or FOR commands by enclosing their names in exclamation-marks.
If you enable this expansion in a script that does not require it, the script behaves different only if it contains names enclosed in exclamation-marks !LIKE! !THESE!. Usually the name is just erased, but if a variable with the same name exist by chance, then the result is unpredictable and depends on the value of such variable and the place where it appears.
The SETLOCAL part is REQUIRED in just a few specialized (recursive) programs, but is commonly used when you want to be sure to not modify any existent variable with the same name by chance or if you want to automatically delete all the variables used in your program. However, because there is not a separate command to enable the delayed expansion, programs that require this must also include the SETLOCAL part.
一个真正的问题经常存在,因为当该批处理文件完成时,内部设置的任何变量都不会被导出。所以它不可能出口,这给我们带来了问题。结果,我只是将注册表设置为始终使用延迟扩展(我不知道为什么它不是默认值,可能是速度或遗留兼容性问题。)
A real problem often exists because any variables set inside will not be exported when that batch file finishes. So its not possible to export, which caused us issues. As a result, I just set the registry to ALWAYS used delayed expansion (I don't know why it's not the default, could be speed or legacy compatibility issue.)