Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Why do parens disrupt program flow? 1

Status
Not open for further replies.

GDameron

Programmer
Aug 8, 2003
39
US
This batch script:
Code:
@echo off
setlocal
goto :main

:sub1
  echo in sub1
  set sub1_called=WAS
goto :eof

:main
set sub1_called=WAS NOT
(
  call :sub1
  echo sub1 %sub1_called% called
)
outputs the counterintuitive result:
Code:
in sub1
sub1 WAS NOT called
...but if the parens are removed, it outputs the expected result:
Code:
in sub1
sub1 WAS called
Why do the parens make a difference?

GD
 
The parens force all the contents of the block to be executed as a single statement which is invalid. This will work:
Code:
@Echo Off
setlocal
goto :main

:sub1
  echo in sub1
  set sub1_called=WAS
goto :eof

:main
set sub1_called=WAS NOT
(
  call :sub1
)
(
  echo sub1 %sub1_called% called

)

[blue]"Well, once again my friend, we find that science is a two headed beast. One head is nice, it gives us aspirin and other modern conveniences,...but the other head of science is BAD! Oh, beware the other head of science, Arthur; it bites!!" - The Tick[/blue]
 
Ok, I did some more testing. It seems that () is akin to opening a new cmd.exe somehow. In this case, I think SetLocal may prevent the commands in the () block from accessing the same environment. Try it without SetLocal. Also, at a command prompt, type (<enter>. Then type some commands seperated by <enter>. Then type )<enter>.

[blue]"Well, once again my friend, we find that science is a two headed beast. One head is nice, it gives us aspirin and other modern conveniences,...but the other head of science is BAD! Oh, beware the other head of science, Arthur; it bites!!" - The Tick[/blue]
 
your paranthesis are incorrect.

you group single commands with them...but in your case you are grouping two commands with them. It will give you an incorrect syntax or invalid parameters error...

you will need to nest your parans,
((call :sub1)echo sub1 %sub1_called% called)

if you really want to use them...i recommend not
hope this helps
chris castelein
shive-hattery
cedar rapids,ia
 
You lost me, Chris - are you saying grouping multiple commands with parens is never appropriate?
 
i dont want to say "appropriate" but more linear...
in your above example there is no need for the () as you were able to see when you removed them. why did you add them in the first place? what im try to say is that they have a place and are mostly used when nesting commands...
you were grouping, which is invalid (in dos)
if you wanted to have multiple commands on a line you can use the & to "group" them...

set X=A & echo %X%

think of () as mathmaitcal:
((1+1)*2) is different than
(1+(1*2))
am i rambling?
chris castelein
 
The reason for starting this thread is to understand what parens actually do, or, more accurately, why they don't do what I expected. I had discovered that a block-if construct like this:
Code:
if <condition> (
    command1
    command2
    command3
}
is not guaranteed to work when environment variables are involved. Often, I was forced to re-code it like this:
Code:
if <condition> command1
if <condition> command2
if <condition> command3
which, frankly, offended my sensibilities. Experimenting revealed that the parens themselves make the behavior change, whether the "if" statement is there or not. Hence the original post. I was (and still am) interested in knowing precisely what parens do to the flow of the command interpreter.

I don't dispute that parens are important for nesting, but your claim that grouping is "invalid" in DOS is puzzling. Putting multiple commands inside an "if" block, with parens, seems to be a reasonable thing to do. Is that not "grouping"? Perhaps I misunderstood.

P.S. I've recently discovered the marvels of "delayed environment variable expansion" (using "cmd /V:ON" and writing !foo! instead of %foo%). Delayed expansion seems to let me write "if" blocks reliably, even when "set" commands are in the picture. But the net effect of using parens remains a mystery.
 
after looking at it a bit more, im not sure why its acting the way it is, but im guessing that with the parens it wants to do everything inside, but your calling a label pulling it out premature and i dont know if it knows what to do.

now to your PS remark about delayed env var expansion.... that is exactly what i was looking for, and i thank you!!!

ive been working on a batch file that would delete large useless files:
REM ***********GENERATES AN EXCLUSION LIST AND THEN COMPARES FILES AND DELETES THEM***********************

FOR /F "tokens=1* delims=:" %%A IN ('XCOPY *.bak? c:\test\ /s /D:%Ndate% /I /L') DO (>>c:\temp\exclude.LST ECHO.%%B)

FOR /F "tokens=1* delims=:" %%A IN ('XCOPY *.bak? c:\test\ /s /L /D:01-01-1997 /EXCLUDE:exclude.LST /I ^| FIND ":"') DO DEL /F %%B


BUT it has a problem with file names that has spaces in them...
so im working on a batch file that will replace spaces with dashes....using the set command, i was tring to get this to work:
set var=X X.ext & set=%var: =-% & set var
as a test...and nothing...seperately it will work
NOW
set var=X X.ext & set=!var: =-! & set var gives me
var=X-X.ext effectively replacing the space with a dash which will let me delete file names with spaces.

thank you.
cdc
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top