使用IF内部FOR循环CMD中的管道内容

问题描述:

我正在编写一个批处理安装程序,我必须在安装过程中检查java版本。 为了做到这一点我用下面的代码在我的批处理:使用IF内部FOR循环CMD中的管道内容

JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF 2 EQU 2 ECHO INSIDE IF STATEMENT.) 

但出于某种原因,这并不工作,出现以下错误信息:

2 was unexpected at this time. 

如果我不管命令到FOR循环,然后IF命令得到执行。 如果我ECHOIF以外的管道,而不使用IF,ECHO得到执行。

因此,由于某种原因管道组合和IF命令不起作用。 我该怎么办?

+2

更奇怪的可执行文件:'如果2 equ 2'不起作用(如果“2”equ“2”'不),但是“if 2 == 2”可以工作... – Stephan

+0

我联系了microsoft,并告诉他们有关st发生在我身上的各种各样的事情,并猜测他们告诉我什么?他们告诉我应该重新安装Windows。 omg,他们很愚蠢,哈哈哈。他们不知道他们在说什么。 –

不幸的是我不能解释为什么它不起作用(我收到2 was unexpected at this time.);但猜测它与IF是由命令解释程序CMD早于所有其他命令识别的命令之一(FOR,IF,REM)以及事件管道(|)初始化新事实CMD任何一方的实例。

有一些可选项,但:

  1. 放置JAVA命令也到FOR /F循环:

    FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`JAVA -version 2^>^&1 ^| FIND "version" /I`) DO (IF 2 EQU 2 ECHO INSIDE IF STATEMENT.) 
    
  2. 使用临时文件:

    1. 阅读临时FOR /F循环内的文件:

      JAVA -version > "%TEMP%\file.tmp" 2>&1 
      FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`^< "%TEMP%\file.tmp" FIND "version" /I`) DO (IF 2 EQU 2 ECHO INSIDE IF STATEMENT.) 
      DEL "%TEMP%\file.tmp" 
      
    2. 读取临时文件FOR /F循环之外:

      JAVA -version > "%TEMP%\file.tmp" 2>&1 
      < "%TEMP%\file.tmp" (FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "version" /I`) DO (IF 2 EQU 2 ECHO INSIDE IF STATEMENT.)) 
      DEL "%TEMP%\file.tmp" 
      
  3. 线上缠绕另一CMD例如明确从IF命令隐藏管:

    JAVA -version 2>&1 | CMD /C FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF 2 EQU 2 ECHO INSIDE IF STATEMENT.) 
    

奇怪的发现:

  • Stephan发现了另一种解决方法:使用比较操作符==,而不是EQU - 见his comment;但是这并不再允许真正的数值整数比较了:

    JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF 2 == 2 ECHO INSIDE IF STATEMENT.) 
    
  • 当你逃脱(至少)SPACE紧跟其后IF^,在命令行工作意外:

    JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF^ 2 EQU 2 ECHO INSIDE IF STATEMENT.) 
    
  • 立即在IF前插入REM/ ^&

    JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (REM/ ^& IF 2 EQU 2 ECHO INSIDE IF STATEMENT.) 
    
+0

我猜这个奇怪的行为其实是cmd中的一个bug。我认为微软应该修复它。 –

+0

是的,我得到了同样的错误。我认为这是CMD错误。无论如何,这个你发布的内容非常棒。谢谢! –

+2

@SYOBSYOT - 此行为不是一个错误,而是cmd.exe的设计方式的一个不幸后果。 IF语句由于管道而被解析两次,这是一个复杂因素,因为IF语法分析器稍微改变了一行。请参阅http://*.com/a/8194279/1012053以获取管道工作方式的解释并间接解释这种行为。另请参见[享受](http://*.com/a/42270214/1012053)和[MC ND](http://*.com/a/42271095/1012053)直接解决解析问题的答案其他方法。 – dbenham

请参阅HERE

因此,代码可以

JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF 2^ EQU 2 ECHO INSIDE IF STATEMENT.) 

这是容易当你明确地定义了符合管道

JAVA -version 2>&1 | CMD /C"FOR /F "TOKENS=2 DELIMS=." %A IN ('FIND "VERSION" /I') DO IF %A EQU 8 (ECHO Java 8) ELSE (ECHO NO Java 8)"