2

我有以下 bat 文件:

@ECHO off
set ErrorThreshold=
set j=5

IF "%ErrorThreshold%"=="" (
  echo a
) ELSE (
  IF %j% GTR %ErrorThreshold% (
    echo b
  ) ELSE (
    echo c
  )
)

如果 ErrorThreshold 没有值,程序会报告The syntax of the command is incorrect.. 如果我设置一个值,一切正常。

有人可以帮我找出问题所在吗?

4

2 回答 2

5

逻辑上,仅当外部 IF 语句为假时,才执行内部 IF 语句。但是批处理一次性解析括号内的复杂语句和块。解析块中的每一行都必须是有效的语法,即使它没有被执行。

正常的变量扩展发生在语句被解析之前。因此,如果未定义变量,则内部 IF 语句变为IF 5 GTR (,这是无效的语法。

您可以通过将两边括在引号中来消除语法错误:IF "%j%" GTR "%ErrorThreshold%". 但是,比较将不是数字的。

你可以在两边都加一个 0。这将保留数字比较,只要数字的大小不超过有符号 32 位整数的限制,它就可以工作:

IF "%ErrorThreshold%"=="" (
  echo a
) ELSE (
  IF %j%0 GTR %ErrorThreshold%0 (
    echo b
  ) ELSE (
    echo c
  )
)

另一种选择是将复杂语句分解为多个语句,如果未使用 GOTO 定义变量,则跳过第二个 IF:

IF "%ErrorThreshold%"=="" (
  echo a
  goto skip
)
IF %j% GTR %ErrorThreshold% (
  echo b
) ELSE (
  echo c
)
:skip

另一种选择是使用延迟扩展,它发生语句被解析之后。IF 语句将!ErrorThreshold!在解析时看到文本,然后该值仅在执行时变为 NULL。但由于之前的 IF 语句,它永远不会被执行,所以一切都很好。

@ECHO off
setlocal enableDelayedExpansion
set ErrorThreshold=
set j=5

IF "%ErrorThreshold%"=="" (
  echo a
) ELSE (
  IF !j! GTR !ErrorThreshold! (
    echo b
  ) ELSE (
    echo c
  )
)

注意:您可以使用if not defined ErrorThreshold代替IF "%ErrorThreshold%"==""

于 2013-08-20T21:00:05.717 回答
2

如果ErrorThreshold什么都没有,那么这一行:

IF %j% GTR %ErrorThreshold% (

扩展为:

IF 5 GTR (

这将导致语法错误,因为缺少等式的右侧。

编辑:@a_horse_with_no_name

它仍然必须解析命令的整个主体才能理解第一个 IF 语句的全部范围。将样本减少到:

IF 1==1 (
  echo a
) ELSE (
  IF 1 GTR (
    echo b )
)

a永远不会回显,因为它必须解析和匹配所有()对。一旦遇到语法错误,它就会退出。

于 2013-08-20T19:34:17.183 回答