1

I am writing one batch setup program, and I have to check version of java during the setup. In order to do that I use the following code in my batch:

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

But for some reason this does not work, there appears the following error message:

2 was unexpected at this time.

If I do not pipe command to FOR loop then IF command gets executed. If I put ECHO outside IF while piping, and do not use IF, ECHO gets executed.

So for some reason combination of piping and IF command does not work. What should I do?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
SYOB SYOT
  • 900
  • 10
  • 14
  • 2
    even stranger: `if 2 equ 2` does not work (also `if "2" equ "2"` doesn't) , but `if 2 == 2` works... – Stephan Feb 16 '17 at 09:39
  • i contacted microsoft, and told them about those strange things which are happening to me, and guess what they told me? they told me that i should reinstall windows. omg, they are so stupid, hahahaha. they do not have a clue what they are talking about. – SYOB SYOT Feb 16 '17 at 11:28

3 Answers3

3

Please see HERE

So the code can be

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

It is easier when you explicitly define the executables that conform the pipe

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 )"
MC ND
  • 69,615
  • 8
  • 84
  • 126
1

Unfortunately I cannot explain why it does not work (I receive 2 was unexpected at this time.); but guess it has something to do with the fact that IF is one of the commands (FOR, IF, REM) that are recognised earlier than all the others by the command interpreter CMD, together with the fact that a pipe (|) initialises new CMD instances for either side.

There are some options however:

  1. Place the JAVA command also into the FOR /F loop:

    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. Use a temporary file:

    1. Read the temporary file within the FOR /F loop:

      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. Read the temporary file outside of FOR /F loop:

      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 around another CMD instance explicitly to hide the pipe from the IF command:

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

Strange findings:

  • Stephan found out another work-around: using comparison operator == instead of EQU -- see his comment; but this does no longer allow true numeric integer comparisons anymore:

    JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF 2 == 2 ECHO INSIDE IF STATEMENT.)
    
  • When you escape (at least) the SPACE immediately behind IF by ^, the command line works unexpectedly:

    JAVA -version 2>&1 | FOR /F "USEBACKQ TOKENS=2 DELIMS=." %A IN (`FIND "VERSION" /I`) DO (IF^ 2 EQU 2 ECHO INSIDE IF STATEMENT.)
    
  • Insert REM/ ^& immediately in front of 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.)
    

Take also a look into this very interesting related thread: What happens with IF command when I pipe to it?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • i guess this strange behavior is actually a bug in the cmd. i think microsoft should fix it. – SYOB SYOT Feb 16 '17 at 09:57
  • yes, i get the same error. i think it is cmd bug. anyway, this what you have posted works great. thank you! – SYOB SYOT Feb 16 '17 at 09:59
  • 4
    @SYOBSYOT - This behavior is not a bug, but rather an unfortunate consequence of how cmd.exe is designed. The IF statement gets parsed twice due to the pipe, which is a complication because the IF parser changes the line a bit. See http://stackoverflow.com/a/8194279/1012053 for an explanation of how pipes work and indirectly explains this behavior. Also see the answers by [enjoying](http://stackoverflow.com/a/42270214/1012053) and [MC ND](http://stackoverflow.com/a/42271095/1012053) that directly solve the parsing problem in other ways. – dbenham Feb 18 '17 at 19:23