2017-02-16 13 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. 

If Я не передаю команду FOR, а затем выполняется команда IF. Если я положил ECHO снаружи IF, пока трубопроводы, и не используют IF, ECHO получает исполнение.

Так что по какой-то причине комбинация трубопроводов и команды IF не работает. Что мне делать?

+2

еще страннее: 'если 2 equ 2 не работает (также 'if" 2 "equ" 2 "' does not), но 'if 2 == 2' works ... – Stephan

+0

Я связался с Майкрософт и рассказал им об этих st что происходит со мной, и угадайте, что они сказали мне? они сказали мне, что я должен переустанавливать окна. omg, они настолько глупы, хахахаха. они не имеют понятия, о чем они говорят. –

ответ

1

К сожалению, я не могу объяснить, почему он не работает (я получаю 2 was unexpected at this time.); но угадайте, что это связано с тем, что IF является одной из команд (FOR, IF, REM), которые распознаются ранее всех остальных командным интерпретатором CMD, а также тот факт, что труба (|) инициализирует новую 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. Wrap вокруг другого 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.) 
    
  • Когда вы убегаете (по крайней мере) в ПРОСТРАНСТВО сразу за 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.) 
    
  • Вставить REM/ ^& непосредственно перед IF:

    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. Я думаю, Microsoft должна это исправить. –

+0

Да, я получаю ту же ошибку. Я думаю, что это ошибка cmd.во всяком случае, это то, что вы опубликовали, отлично работает. Спасибо! –

+2

@SYOBSYOT - Такое поведение не является ошибкой, а скорее неудачным следствием того, как разработан cmd.exe. Оператор IF дважды анализируется из-за канала, что является сложностью, потому что парсер IF немного меняет строку. См. Http://stackoverflow.com/a/8194279/1012053 для объяснения того, как работают трубы, и косвенно объясняет это поведение. Также см. Ответы [enjoying] (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)"