i call this bath file in another batch file.
... get path1, path2
call IsPathRelative.bat path1
if %IsPathRelative% =="True" dosomething
if %path2%=="" (
call IsPathRelative.bat path2
if %IsPathRelative% =="" do other ) <--------------------for example
if path2 is relative path, it should be True, but actually it is
False. i have traced into IsPathRelative batch file , everything's
fine . before it leaves IsPathRelative file scope, %IsPathRelative% is
still True. why this happens?
//file1.bat
@set test=False
@if "%1" == "" @set test=True
//file2.bat
@if /i not "%1" == "" @(
@call file1.bat parameter
@echo %test%) <-----------------when i run file3.bat. this sentence
doesn't work, variable "test" seems hasn't been defined?? but it
should have been defined in file1
@call file1.bat
@echo %test%
//file3.bat
call file2.bat parameter
This is the effect of the way the command processor evaluates
environment variables. Specifically, it is generally done in one pass
- when the statement is initially parsed. Therefore, any alterations
to a variable that follow this evaluation are ignored. Since this is
often a problem, the processor provides a parameter to overcome this
limitation, called delayed expansion. It is invoked through the
SETLOCAL statement ...
SETLOCAL enabledelayedexpansion
and accessed through the substitution of exclamation points for
percent signs.
::file1.bat
@set test=False
@if "%1" == "" @set test=True
::file2.bat
SETLOCAL enabledelayedexpansion
@if /i not "%1" == "" @(
@call file1.bat parameter
@echo !test!)
I don't follow the logic of your examples, but that's the gist of what
you need. See the help for SET and SETLOCAL for more information and
examples.
Tom Lavedas
===========
http://members.cox.net/tglbatch/wsh/
Since the 'call' statement in file2 occurs within a branch of the code,
you'll need to use delayed expansion and reference the variable using
bangs '!' as opposed to the percent '%' symbols. Without it, the entire
branch of code is expanded (treated as one line) at runtime as you enter
into it which means '%test%' resolves to nul since it has yet to be
set -
-- file1
set test=False
if "%1" == "" set test=True
-- file2
if /i not "%1" == "" (
call file1 %*
echo !test!
)
-- file3
setlocal ENABLEDELAYEDEXPANSION
call file2 parameter
--
Dean Wells [MVP / Directory Services]
MSEtechnology
[[ Please respond to the Newsgroup only regarding posts ]]
R e m o v e t h e m a s k t o s e n d e m a i l
It's a battle between this question and date/time manipulation for #1 FAQ
status.
See Timo's FAQ in alt.msdos.batch.nt.
Batch parses the ENTIRE "IF" statement and substitutes the values of
%variable% AT THAT TIME.
THEN the "IF" statement is EXECUTED.
You are changing the value of ispathrealtive AFTER it has been parsed, and
batch executes the statement using the value AT PARSE TIME.
There are two common cures:
1. Before the IF statement (normally at the start of the batch) execute a
SETLOCAL ENABLEDELAYEDEXPANSION
statement. You may also need to add the ENABLEEXTENSIONS keyword to this
statement.
THEN use !variable! in place of %variable% to access the RUN-TIME (dynamic)
value of the variable - %variable% accesses the PARSE-TIME value.
(see
SETLOCAL /?
from the prompt, or alt.msdos.batch.nt for documentation/explanation)
This has the drawback that any environment changes made after the SETLOCAL
statement will be UNDONE when the batch terminates. (This can be bypassed -
see alt.msdos.batch.nt & alt.msdos.batch.nt FAQ for more info)
2. Use an internal routine call
...
IF .... CALL :INTERNAL
...
GOTO :EOF
:INTERNAL
:: variables values here are OUTSIDE of the context of the IF
...
GOTO :EOF
Note that the colons are important.
(see
CALL /?
from the prompt, or alt.msdos.batch.nt & alt.msdos.batch.nt FAQ for
documentation/explanation)
BTW:
are you aware that an
@ECHO OFF
statement will turn command-echoing OFF for the ENTIRE batch file - which
means you don't have to put "@" before each statement?
You can turn echoing on again with
@ECHO ON
for debugging purposes - commands will be echoed until another @ECHO OFF
statement is encountered.
function.bat ::"function" variable is only set in function.bat
if (%function%)==(True) echo succeed
should i use delayedexpansion technique also? it works in some cases
and failed in other.
ECHO OFF
set build=True
setlocal enabledelayedexpansion
::read configfile
::build several project and output to log file
endlocal
for /f %%i in ('findstr /s /r /i /c:"[1-9][0-9]* Error\(s\)" D:
\StateMachine\src\IDE\log\*.log') do @goto error
for /f %%i in ('findstr /s /r /c:"[1-9][0-9]* failed" D:\StateMachine
\src\IDE\log\*.log') do @goto error
goto eof
:error
@set build=False
echo %build% in test1.bat
:eof
::test2.bat
ECHO OFF
call test1.bat
ECHO %test1% in test2.bat
when i run test2.bat, i get following output:
False in test1.bat
True in test2.bat
why this happened?
delayed expansion *always* *works* - the way it was intended to. When your
efforts tend to show otherwise, I'd suggest you consider examining how you
are using it and/or what, precisely, you think it is supposed to do.
/Al
>::test1.bat
>
>ECHO OFF
>set build=True
>
>setlocal enabledelayedexpansion
> ::read configfile
> ::build several project and output to log file
>endlocal
What is endlocal doing there?
>for /f %%i in ('findstr /s /r /i /c:"[1-9][0-9]* Error\(s\)" D:
>\StateMachine\src\IDE\log\*.log') do @goto error
>for /f %%i in ('findstr /s /r /c:"[1-9][0-9]* failed" D:\StateMachine
>\src\IDE\log\*.log') do @goto error
Both these commands goto the :error routine
>goto eof
>
>:error
>@set build=False
>echo %build% in test1.bat
>:eof
>
>
>::test2.bat
>ECHO OFF
>call test1.bat
>ECHO %test1% in test2.bat
%text1% is not set in the code above.
Not 100% sure, but I think the complexity of your coding standards may be
making it more difficult to find your problems. Here are a few suggestions
for your consideration:
1) never define a label called ":eof", as ":eof" is automatically defined as
immediately following the last line in the file. If you define it
explicitly, you might be tempted to add some code to be executed on exit
like this:
if some-error-condition goto:eof
etc.
etc.
goto:eof
:eof
echo/the result is...
pause
The statements following the ":eof" label will never be executed.
2) what do you think happens when this code runs:
set test=a
if "%test%" EQU "a" (
echo/equal
) else (
echo/not equal
)
You might say that it will display the word "equal", but it will not,
because there is a trailing blank in the set statement. Do this instead:
(set test=a)
if "%test%" EQU "a" (
echo/equal
) else (
echo/not equal
)
the variable test will now contain what seemed to be the most likely and
expected value.
3) when a function returns a boolean result (i.e. true or false), there is
little benefit in prettying up the code by capitalizing the first letter,
but there is a disadvantage: unnecessary complexity. Consider this:
(set test=True)
if "%test%" EQU "true" (
echo/TRUE
) else (
echo/FALSE
)
if "%test%" EQU "false" (
echo/FALSE
) else (
echo/TRUE
)
The output will be the seemingly illogical: FALSE then TRUE. Better to use
true/false values that are less ambiguous, such as:
(set test=true)
call:showresult
(set test=)
call:showresult
goto:eof
:showresult
if defined test (
echo/test is true
) else (
echo/test is false
)
/Al