Batch script set command not working properly

2019-05-30 08:27发布

问题:

I am trying to read the first line from a file and I am setting it as environment variable. Below is the variable I use

@echo off
if EXIST "test.dat" (
    set JAVA_HOME_PATH=
    set JAVA_PATH=
    set /p JAVA_HOME_PATH=<test.dat
    echo %JAVA_HOME_PATH%
    set JAVA_PATH=%JAVA_HOME_PATH%\bin\java
    echo %JAVA_PATH%
  )

Assuming the test.dat contains the path to JDK and if it is c:\JDK1.6

on running it for the first time I get

ECHO is off.
ECHO is off.

on running again I get

c:\JDK1.6
\bin\java

and on running again I get

c:\JDK1.6
c:\JDK1.6\bin\java

I dint change the test.dat file. But why is this happening ? Only when I run for third time all the variables getting set ? Looks weird. Am I doing anything wrong in this ? Please help me out.

回答1:

Batch always replaces any %var% in any statement with its CURRENT value and THEN runs the statement. Your IF statement runs from the IF keyword to the closing-parenthesis.

On the first run, batch substitutes (nothing) for Java_home_path and for java_path so the ECHO %java_home_path% is interpreted as 'echo` and batch reports its ECHO status.

HOWEVER, java_home_path is set to c:\JDK1.6 from test.dat but JAVA_PATH is set to (nothing)\bin\java

On the second run, these existing values are duly reported, java_home_path is set from test.dat and JAVA_PATH is set to c:\JDK1.6\bin\java

On the third run, you get the names you expect reported.

Cure: (1)

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
if EXIST "test.dat" (
    set JAVA_HOME_PATH=
    set JAVA_PATH=
    set /p JAVA_HOME_PATH=<test.dat
    echo !JAVA_HOME_PATH!
    set JAVA_PATH=%JAVA_HOME_PATH%\bin\java
    echo !JAVA_PATH!
  )

cure: (2)

@echo off
if not EXIST "test.dat" ECHO No test.dat&goto :eof
set JAVA_HOME_PATH=
set JAVA_PATH=
set /p JAVA_HOME_PATH=<test.dat
echo %JAVA_HOME_PATH%
set JAVA_PATH=%JAVA_HOME_PATH%\bin\java
echo %JAVA_PATH%


回答2:

Your issue is one of Delayed Expansion of variables.

To fix it, simply change your script to include SETLOCAL ENABLEDELAYEDEXPANSION, and use !! instead of %% as so:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
if EXIST "test.dat" (
    set JAVA_HOME_PATH=
    set JAVA_PATH=
    set /p JAVA_HOME_PATH=<test.dat
    echo !JAVA_HOME_PATH!
    set JAVA_PATH=!JAVA_HOME_PATH!\bin\java
    echo !JAVA_PATH!
)