美文网首页
Windows batch script的setlocal En

Windows batch script的setlocal En

作者: CodingCode | 来源:发表于2023-03-04 02:16 被阅读0次
  1. 要回答这个问题,先要解释一点batch脚本的执行过程

Batch脚本的执行,按行为单位,读入一行,分析一行(parse),执行一行(execute)。

  • 一行指的是一条完整语句,所以一个语句块(所有括号括起来的多条语句)也是作为一行处理的。
  if condition (
     statement1
     statemetn2
     statement3
  )

上述这个if语句就是作为一行来处理的,一次性分析(parse)。

  • 分析过程要做很多事,包括变量替换,把%VAR%替换成值,以及把双%%替换成单%。
  • 然后执行。
  1. 有了这个背景,下面我们抛出需求解决的问题
@echo off

setlocal

set INPUT=aaa.bat

IF  u==u (
  set OUTPUT=%INPUT%
  echo INPUT=%INPUT%, OUTPUT=%OUTPUT%
)

endlocal

运行一下:

INPUT=aaa.bat, OUTPUT=

问题是OUTPUT没有值,是不是很奇怪。这其实就是脚本分析的流程;
前面我们提到语句块"()"是作为一行来一起分析的,所以这里:

IF  u==u (
  set OUTPUT=%INPUT%
  echo INPUT=%INPUT%, OUTPUT=%OUTPUT%
)

其分析阶段结束后,这等于是

IF  u==u (
  set OUTPUT=aaa.bat
  echo INPUT=aaa.bat, OUTPUT=
)

因为是一次性分析的,所以前面的set OUTPUT=语句的结果并没有作用到后一条输出语句,前面set语句是执行后OUTPUT才有希望的值,这就是分行和执行的差异。

解决办法是使用延迟扩展(EnableDelayedExpansion),让后一条的echo语句延迟扩展,指定前面的set语句执行完成;语法是:

  1. 定义setlocal EnableDelayedExpansion
  2. 使用!var!代替%var%,表示这个变量要延迟扩展。
@echo off

setlocal

set INPUT=aaa.bat

setlocal EnableDelayedExpansion
IF  u==u (
  set OUTPUT=%INPUT%
  echo INPUT=%INPUT%, OUTPUT=!OUTPUT!
)
endlocal

endlocal

几点注意:

  1. 替换%OUTPUT%!OUTPUT!,表示OUTPUT变量需要延长扩展。
  2. 格式%VAR%还是保留在分析(parse)阶段替换,只是!VAR!延迟到执行阶段才替换。
  3. 至于INPUT变量,也可以替换成!INPUT!,这个例子没有替换,是因为INPUT的值没有发生变化,在整个if块分析阶段值已经确定,且不再变化。

相关文章

网友评论

      本文标题:Windows batch script的setlocal En

      本文链接:https://www.haomeiwen.com/subject/nxoeldtx.html