2017-02-16 187 views
1

我正在編寫一個批處理安裝程序,我必須在安裝過程中檢查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,他們很愚蠢,哈哈哈。他們不知道他們在說什麼。 –

回答

1

不幸的是我不能解釋爲什麼它不起作用(我收到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://stackoverflow.com/a/8194279/1012053以獲取管道工作方式的解釋並間接解釋這種行爲。另請參見[享受](http://stackoverflow.com/a/42270214/1012053)和[MC ND](http://stackoverflow.com/a/42271095/1012053)直接解決解析問題的答案其他方法。 – dbenham

3

請參閱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.) 
3

這是容易當你明確地定義了符合管道

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)"