我需要根据 Windows 批处理脚本的参数设置一些变量。
@echo off
if [%1]==[] (
echo "Usage: xxx <AAA|ZZZ>"
) else (
if [%1]==[AAA] (
SET SOURCE_DIR=c:\dirA
) else if [%1]==[ZZZ] (
SET SOURCE_DIR=c:\dirZ
)
echo Source dir is: %SOURCE_DIR%
)
当我使用参数调用上述脚本时AAA,我得到输出
Source dir is: c:\dirA
第二次通话后。从那时起,当我交替使用AAA和雙方,我得到了这个模式:
C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA
C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA
因此,看起来我正在操作一个全局变量,该变量即使在脚本完成后也可用。这一点并不困扰我,但新设置仅在后脚本终止是一个问题,因为我的脚本的其余部分依赖于它(显然)。
在这种情况下,局部变量的正确用法是什么?如何解释上述“延迟状态设置”的奇怪行为?
谢谢!
答案1
批处理文件中的变量默认在脚本执行开始时扩展;您需要使用延迟扩展,可以使用“!”分隔符:
echo Source dir is: !SOURCE_DIR!
这仅在命令解释器启用了延迟扩展时才有效,默认情况下不是;因此您需要在启动解释器时启用它,使用CMD.EXE /V
。
您也可以在批处理文件中使用此语句启用它:
setlocal ENABLEDELAYEDEXPANSION
更多信息这里。
答案2
我本可以处理得更简单一些……
@ECHO OFF
SET SOURCE_DIR=
IF /I [%1]==[AAA] SET SOURCE_DIR=c:\dirA
IF /I [%1]==[ZZZ] SET SOURCE_DIR=c:\dirZ
IF [%SOURCE_DIR]==[] (
ECHO "Usage: xxx <AAA|ZZZ>"
EXIT 1
)
ECHO Source dir is: %SOURCE_DIR%
我必须承认,我有点困惑,为什么这个方法有效,而问题中的例子却不行。我最好的猜测是,这是一个范围问题。因为在示例中,变量 SOURCE_DIR 是在括号内设置的,所以它在根范围内的值保持不变。我的脚本在根范围内更改了 SOURCE_DIR。
至于为什么延迟扩展技巧会导致它拾取更深一层范围的更改,似乎扩展发生在每次范围更改的开始。因此,通过延迟,您基本上是在强制它在返回根范围后重新扩展。