Tags

,

One trick thing in Windows Batch is how it substitutes variable value: Variable expansion occurs when the command is read. This is especially confusing in if, for and multiple statements block.

If you run the following script, the output would be: VAR is still: first here: first
set VAR=first
if “%VAR%” == “first” (
set VAR=second
echo VAR is still: first here: %VAR%
if “%VAR%” == “second” @echo You will never see this
)
The batch processor treats the whole if block as one command, it expands the variables once and only once, before it executes the if block, so it is actually run:
if “first” == “first” (
set VAR=second
echo VAR is still: first here: first
if “first” == “second” @echo You will never see this
)
EnableDelayedExpansion
The rescue is Delayed Expansion, it will cause variables to be expanded at execution time rather than at parse time. It is enabled by Setlocal EnableDelayedExpansion, and use !variable_name! to tell batch processor to expand variable value at runtime.
Practical Example: Get jvm.dll path
When use Apache Procrun to wrap one Java Application as windows Services as described in this article: Windows BAT: Using Apache Procrun to Install Java Application As Windows Service

We try to get jvm.dll path from environment variable: APP_JAVA_HOME, JAVA_HOME, and set its value to PR_JVM.
The final version is like this:

//<![CDATA[
if(showAdsense){
document.write("(adsbygoogle = window.adsbygoogle || []).push({});”)
}
//]]>

@echo off 
setlocal enabledelayedexpansion
set PR_JVM=auto
IF “%PR_JVM%” == “auto” (
set NEW_JAVA_HOME=%CV_JAVA_HOME%
if “!NEW_JAVA_HOME!” == “” (
set NEW_JAVA_HOME=%JAVA_HOME%
)
echo Using NEW_JAVA_HOME: !NEW_JAVA_HOME!
  IF not “!NEW_JAVA_HOME!” == “” (
 echo !NEW_JAVA_HOME! not empty, try to use it.
 for /F “delims=” %%i in (‘dir “!NEW_JAVA_HOME!” /B /S  /a-d ^| findstr jvm.dll’) do (
echo found “%%i”
set “NEW_PR_JVM=%%i”
)
 IF exist “!NEW_PR_JVM!” (
 SET “PR_JVM=!NEW_PR_JVM!”
echo NEW_PR_JVM: !NEW_PR_JVM!
)
  )
)
echo final PR_JVM: %PR_JVM%
“%PRUNSRV%” “//US//%SERVICE_NAME%” –DisplayName “%PR_DESPLAYNAME%” –Description “%PR_DESCRIPTION%” –StdOutput auto –StdError auto ^
–Classpath=”%MYCLASSPATH%” –Jvm=”%PR_JVM%” –JvmOptions=”%PR_JAVA_OPTIONS%” –StartPath “%APP_HOME%” –Startup=auto ^
–StartMode=jvm –StartClass=StartClass –StartParams=”%START_PARAMS%” ^
–StopMode=jvm  –StopClass=StopClass  –StopParams=”%STOP_PARAMS%”

ENDLOCAL

The output looks like:
Using NEW_JAVA_HOME: C:\Program Files\Java\jdk1.6.0_38
C:\Program Files\Java\jdk1.6.0_38 not empty, try to use it.
found “C:\Program Files\Java\jdk1.6.0_38\jre\bin\server\jvm.dll”
NEW_PR_JVM: C:\Program Files\Java\jdk1.6.0_38\jre\bin\server\jvm.dll
final PR_JVM: C:\Program Files\Java\jdk1.6.0_38\jre\bin\server\jvm.dll

The origin version is like, which doesn’t work because how batch processor expand variable value:
@echo off 
setlocal
set PR_JVM=auto
rem set CV_JAVA_HOME=
IF “%PR_JVM%” == “auto” (
set NEW_JAVA_HOME=%CV_JAVA_HOME%
if “%CV_JAVA_HOME%” == “” (
set NEW_JAVA_HOME=%JAVA_HOME%
)
echo Using NEW_JAVA_HOME: %NEW_JAVA_HOME%
  IF not “%CV_JAVA_HOME%” == “” (
 echo %CV_JAVA_HOME% not empty, try to use it.
 for /F “delims=” %%i in (‘dir “%CV_JAVA_HOME%” /B /S  /a-d ^| findstr jvm.dll’) do (
echo found “%%i”
set “NEW_PR_JVM=%%i”
)
 IF exist “%NEW_PR_JVM%” (
 SET “PR_JVM=%NEW_PR_JVM%”
echo NEW_PR_JVM: %NEW_PR_JVM%
)
  )
)
echo final PR_JVM: %PR_JVM%
ENDLOCAL

The output looks like:
Using NEW_JAVA_HOME:
C:\Program Files\Java\jre7 not empty, try to use it.
found “C:\Program Files\Java\jre7\bin\server\jvm.dll”
final PR_JVM: auto

Resources
EnableDelayedExpansion
Environment variable expansion occurs when the command is read
Batch file :How to set a variable inside a loop for /F
http://ift.tt/KAi7t8

via Blogger http://ift.tt/1fYbLSv

Advertisements