Cmd 为什么';分支是否正确?

Cmd 为什么';分支是否正确?,cmd,Cmd,我已经问过了 我试图使用IF-DEFINED来控制分支,但它不起作用。我将从一个例子开始 setLocal if defined _var ( :: _var is NOT defined, so the next line should not be executed if %_var%=="test" echo %_var% is defined ) endLocal 处理在命中ECHO语句时停止,并以“ECHO此时意外”退出。错误消息。 问题是嵌套的IF语句正在执行,不应该执行

我已经问过了

我试图使用IF-DEFINED来控制分支,但它不起作用。我将从一个例子开始

setLocal
if defined _var (
::  _var is NOT defined, so the next line should not be executed
    if %_var%=="test" echo %_var% is defined
)
endLocal
处理在命中ECHO语句时停止,并以“ECHO此时意外”退出。错误消息。 问题是嵌套的IF语句正在执行,不应该执行,因为没有定义_var。我怎样才能解决这个问题

谢谢,
Shane.

您真正的问题是没有正确匹配if语句。要进行解释,请参见以下示例

if a == "a"..
vs

因此,在您的示例中,您试图匹配:

if test=="test"..
我们在变量两边使用双引号的原因是为了确保消除可能成为测试值一部分的任何可能的空白

所以这个版本应该可以。我添加了
/I
开关以匹配
test
不区分大小写,因此它将在任何情况下的组合中匹配
test
<代码>测试,
测试
测试
测试
等:

setLocal
set /p "_var=Enter Variable name: "
set "_var=%_var:"=%"
if defined _var (
:# rem _var is NOT defined, so the next line should not be executed
    if /i "%_var%"=="test" echo %_var% is defined
)
endLocal

真正的问题是没有正确匹配if语句。要进行解释,请参见以下示例

if a == "a"..
vs

因此,在您的示例中,您试图匹配:

if test=="test"..
我们在变量两边使用双引号的原因是为了确保消除可能成为测试值一部分的任何可能的空白

所以这个版本应该可以。我添加了
/I
开关以匹配
test
不区分大小写,因此它将在任何情况下的组合中匹配
test
<代码>测试,
测试
测试
测试
等:

setLocal
set /p "_var=Enter Variable name: "
set "_var=%_var:"=%"
if defined _var (
:# rem _var is NOT defined, so the next line should not be executed
    if /i "%_var%"=="test" echo %_var% is defined
)
endLocal

这个小代码块存在多个问题

第一个问题是使用带有
的无效标签在命令块中写入注释,该命令块以
开始,以
结束匹配)
。命令块内不允许有标签。在0个或更多空格/制表符后以
开头的行会导致在执行命令块时出现未定义的行为。未定义的行为意味着它可以偶然工作,但也可能偶然失败。执行行为未定义

注释的命令是REM。在命令提示符窗口中运行
rem/?
,获取此命令的帮助信息

请注意,REM是一个命令,因此带有REM的注释行由Windows命令处理器解析,就像注释行上的任何其他重要命令行一样,包含
%variable%
或类似
&
的运算符。因此,在评论文本中写什么要小心


第二个问题是评论本身是不正确的

_未定义var,因此不应执行下一行

此注释是错误的,因为环境变量
\u var
是在执行命令
后到达此行的
cmd.exe上明确定义的,如果定义了
,结果为正


第三个问题是,
if%\u var%=“test”
在语法上不是100%正确的。比较运算符
==
周围缺少空格。但是,在处理批处理文件时,
cmd.exe
会通过在运算符
=
周围插入两个缺少的空格来自动检测此语法错误。这可以在电视上看到


第四个问题是,IF总是比较两个字符串,并在字符串比较中包含双引号。因此,在使用
if%\u var%==“test”
或语法正确的
if%var%==“test”
时,仅当分配给环境变量
\u var
的是带双引号的字符串
“test”
时,该条件才为真。此字符串比较在定义的
\u var
上的所有其他情况下计算为false。如果之前没有导致语法错误,请参阅下一期

请阅读我关于如何通过命令IF进行字符串比较的详细说明的回答


第五个问题是Windows command processor在执行命令IF之前解析整个命令块,从
开始,以匹配的
结束)。

没有环境变量
\u var
的内部IF在分析行中的命令块时会产生以下结果:

if =="test" echo is defined
cmd.exe
在此命令行上检测到严重的语法错误,并在执行外部IF条件之前退出批处理文件处理

一种解决方案是将
%var%
括在双引号中,即在批处理文件中使用:

if "%_var%" == "test" echo %_var% is defined
如果在解析命令块时未定义环境变量
\u var
,则此IF命令行是正确的

setlocal EnableExtensions EnableDelayedExpansion
if defined _var (
    rem  _var is defined, so the next line should be executed.
    if "!_var!" == "test" echo _var is defined with !_var!.
)
endlocal
但是,如果定义了
\u var
,并且包含一个或多个
,则此解决方案不起作用,因为双引号会再次导致命令行的语法无效,如果

此外,如果分配给环境变量的字符串包含以下字符之一,则
echo
不会导致打印环境变量的值
\u var
。在这种情况下,由于字符串比较结果为false,因此不会执行
echo

因此,更好的解决方案是通过延迟环境变量扩展启用和引用环境变量
\u var
的值,以避免此环境变量的值在解析整个命令块后修改命令行以通过
cmd.exe
执行

setlocal EnableExtensions EnableDelayedExpansion
if defined _var (
    rem  _var is defined, so the next line should be executed.
    if "!_var!" == "test" echo _var is defined with !_var!.
)
endlocal
还必须启用命令扩展,因为如果定义了
(否则)
(如果定义)
(否则)将不受命令的支持