Windows cmd shell : if-then-else weirdness for block statements

标签 windows batch-file cmd

尝试设置一个简单的构建脚本,该脚本将根据其他环境变量扩展路径。这个小脚本运行良好:

echo off
call c:\vstudio\vc\bin\vcvars32.bat
set _ISGIT=1
echo current path is %PATH%
if defined _ISGIT set PATH=c:\git\bin;%PATH%

但是如果我想根据 _ISGIT 变量的存在执行多行,那么我认为这会起作用

echo off
call c:\vstudio\vc\bin\vcvars32.bat
set _ISGIT=1
echo current path is %PATH%
if defined _ISGIT (
    set PATH=c:\git\bin;%PATH%
    set PATH=c:\foo;%PATH%
)

但这会产生以下输出:

D:\>test.cmd

D:\>echo off
current path is C:\vstudio\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\MSBuild\14.0\bin;C:\
vstudio\Common7\IDE\;C:\vstudio\VC\BIN;C:\vstudio\Common7\Tools;C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319;C:\vstudio
\VC\VCPackages;C:\Program Files (x86)\HTML Help Workshop;C:\vstudio\Team Tools\Performance Tools;C:\Program Files (x86)\
Windows Kits\10\bin\x86;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\;C:\ProgramData\Oracl
e\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\U
sers\jselbie\.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files (x86)\Windows Kits\10\Windows Performance To
olkit\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\nodejs\;C:\Program Files (x86)\Skype\Phone\;C:\WINDOWS\s
ystem32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Co
rporation\PhysX\Common;C:\Users\jselbie\.dnx\bin;C:\Users\jselbie\AppData\Roaming\npm;%USERPROFILE%\AppData\Local\Micros
oft\WindowsApps;

MSBuild\14.0\bin was unexpected at this time.

MSBuild\14.0\bin 是意外的 可能是包含带空格的目录的原始路径的副作用。带有 () 的扩展命令中存在空格似乎会使脚本失效。

如何解决这个问题,而无需使用独立的 if Defined 语句?

最佳答案

有两件事是错误的。首先,路径中的目录之一包含括号。变量扩展是在解析之前执行的,因此 PATH 中的右括号被视为 IF block 的右括号。要解决此问题,您需要将分配放在引号中:set "PATH=..."

其次,在 block 内(用括号表示),整个 block 中的所有环境变量首先立即展开。然后解析该 block 。这意味着第二行中的扩展路径与第一行中的相同。第一行没有改变它。要解决此问题,您应该在一行中完全更改路径:

if defined _ISGIT (
    set "PATH=c:\foo;c:\git\bin;%PATH%"
)

或使用延迟扩展:

setlocal enabledelayedexpansion
if defined _ISGIT (
    set "PATH=c:\git\bin;!PATH!"
    set "PATH=c:\foo;!PATH!"
)

Delayed expansion通过在稍后阶段扩展变量来工作,即在第一行分配变量之后。必须使用 setlocal 命令启用它才能使用。

关于Windows cmd shell : if-then-else weirdness for block statements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42360991/

相关文章:

windows - 批处理文件创建日志文件

arrays - 使用 cmd 创建一组文件夹 - 设置带有空格的循环变量

excel - 解决 Excel 中生成的 .Bat 的 VBA 类型不匹配问题

batch-file - 将变量回显到文件中

visual-studio - 使用批处理文件在当前文件夹中运行 Visual Studio 代码

java - 如何以编程方式将私钥添加到 Windows 证书存储

c# - 使用 HockeyApp(Windows) 发送已处理的异常报告

windows - 在文件名中使用通配符的 Invoke-WebRequest -OutFile <filename>

c - 在 C 程序中获取(星号)作为输入

unit-testing - "pause"被忽略