简体   繁体   中英

windows batch: “if exist” — path exists but it says no — why?

I have this script in my batch file --

if not exist "%JAVA_HOME%" (
    echo JAVA_HOME '%JAVA_HOME%' path doesn't exist) --- (1)
else (
    echo Setting JAVA property to '%JAVA_HOME%\bin\java' --- (2)
        set "JAVA=%JAVA_HOME%\bin\java")

%JAVA_HOME% was set to C:\\Program Files (x86)\\Java\\jdk1.7.0_45 . This location exists on my machine but the above code executes line (1), why ?

FOLLOW-UP:

It's driving me crazy, I have this script now --

if "x%JAVA_HOME%" == "x" (
  set  JAVA=java
  echo JAVA_HOME is not set. Unexpected results may occur.
  echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
) else (
  if not exist "%JAVA_HOME%" (
    echo Here ----------------------------------> note this line !!
    echo JAVA_HOME '%JAVA_HOME%' path doesn't exist
    goto END
  ) else (
    echo Setting JAVA property to '%JAVA_HOME%\bin\java'
    set "JAVA=%JAVA_HOME%\bin\java"
  )
)
:END

the %JAVA_HOME% is set properly (it's C:\\Program Files (x86)\\Java\\jdk1.7.0_45 ). but when I run, I get this error --

prompt> test.bat
prompt> \Java\jdk1.7.0_45' was unexpected at this time
prompt>      echo JAVA_HOME 'C:\Program Files (x86)\Java\jdk1.7.0_45' path does not exist

what is going on? Please also notice that the line echo Here does not execute as well.

Raymond Chen once said :

The batch language was not designed; it evolved.

Which makes it full of quirks. One of them is that it is picky about parenthesis.

The following code works on my machine :

@echo off

if not exist "%JAVA_HOME%" (
    echo JAVA_HOME '%JAVA_HOME%' path doesn't exist
) else (
    echo Setting JAVA property to '%JAVA_HOME%\bin\java'
    set JAVA=%JAVA_HOME%\bin\java
)

I used ) else ( , a single parenthesis on a line by itself, and removed the parethesis from the echo statement.

You might also want to check the double quotes. Puttint the variable name inside the quotes like you did will remove the quotes from value. Here is an example :

C:\>set "test=foo bar"

C:\>echo %test%
foo bar

C:\>echo "%test%"
"foo bar"

If you need quotes in the variable's value then put them on the right hand side, like this :

C:\>set test="foo bar"

C:\>echo %test%
"foo bar"

Starting from scratch, going for former gives you more flexibilty (see @foxidrive comment), but it all depends on what you have to work with.

The parentheses in your JAVA_HOME path are messing up the if statements. I know it is painful but I recommend using the 8dot3 name.

call :SET8DOT3 JAVA_HOME %JAVA_HOME%


:SET8DOT3
set %1=%~fs2
goto :END

So the whole thing becomes...

call :SET8DOT3 JAVA_HOME "%JAVA_HOME%"

if "x%JAVA_HOME%" == "x" (
  set  JAVA=java
  echo JAVA_HOME is not set. Unexpected results may occur.
  echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
) else (
  if not exist "%JAVA_HOME%" (
    echo Here ---------------------------------- note this line !!
    echo JAVA_HOME "%JAVA_HOME%" path doesn't exist
    goto END
  ) else (
    echo Setting JAVA property to "%JAVA_HOME%\bin\java"
    set "JAVA=%JAVA_HOME%\bin\java"
  )
)
goto :END

:SET8DOT3
set %1=%~fs2

:END

Batch recognises "double quotes" to delimit a quoted string, 'but NOT single quotes'

Hence, it's chapter 2 of parenthesis-confusion.

BTW -

if defined var (echo var is defined
) else (
  echo var is not defined
)

Is better than if [not] "x%var%"=="x"

And I'm perpetually bemused by the construct

if not something (echo not something
 ) else (
 echo something
)

What's wrong with

if something (echo something
 ) else (
 echo not something
)

which disposes of the logical gymnastics?

  • but I suppose it's a matter of style - or possibly lack thereof...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM