Limits on Parens in Batch files

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Is there any documentation on the use of parens for grouping commands? I
seem to be running into some kind of limit on the either the number of
commands or maybe it is the number of characters. It is very difficult to
track down exactly where the wall is, it seems to be different depending on
the commands within the parens.

I think the concept is that whatever is in parens is turned into one long
line and then executed, but I would appreciate some actual facts.

Does anyone have any?
Thanks
HHH
 
HipHopHank said:
Is there any documentation on the use of parens for grouping commands? I
seem to be running into some kind of limit on the either the number of
commands or maybe it is the number of characters. It is very difficult to
track down exactly where the wall is, it seems to be different depending on
the commands within the parens.

I think the concept is that whatever is in parens is turned into one long
line and then executed, but I would appreciate some actual facts.

Does anyone have any?

Without seeing the problematic code, it is difficult give any hints.
The command line length is AFAIK limited to 2046 chars in nt/w2k and
8190 in xp.

IMO there are ways to avoid to much/great parens (aereas) with internal
subs, setlocal and delayedexpansion.

HTH
 
HipHopHank said:
Is there any documentation on the use of parens for grouping commands? I
seem to be running into some kind of limit on the either the number of
commands or maybe it is the number of characters. It is very difficult to
track down exactly where the wall is, it seems to be different depending on
the commands within the parens.

I think the concept is that whatever is in parens is turned into one long
line and then executed, but I would appreciate some actual facts.

Does anyone have any?
Thanks
HHH

There is actually no practical limit to the number of lines a "command" can
have under NT, 2000, XP or Server 2003. You are correct in stating that
parens are turned into one long line before execution. This is generally a
good thing and speeds execution as the "logical line" is read by the Cmd.exe
all at once rather than one physical line at a time.

The "data" in the command line (including the expanded value of any
variables) does have some limits but these can usually be overcome.

An example of a multi-line, "long" command is at
(http://TheSystemGuard.com/NTCmdLib/GuardNotes/ErrorCodes.htm)

Post an example of the code you are having a problem with and we would be
happy to assist.

-tsg

/-----------------+---------------+----------------------\
| COMPATIBILITY | CLARITY | SPEED |
| Write code ONCE | Make it clear | THEN...Make it fast! |
\-----------------+---------------+----------------------/
400+ command-line resources using ONLY native NT commands!
(http://TheSystemGuard.com/default.asp#MasterCommandList)
 
The code I was having a problem with invoved several labels and the goto
command. All the labels and the goto's were within the parens, but they just
seemed to make the command processor nuts. The best I could do was get a
single pass through the for loop and then the program stopped. I don't know
at this point if it is the 'FOR' command or the Parens that had the problem.
I solved it by using the call command to call a label within the file. That
is working fine.


This works:

@echo off
setlocal enableextensions enabledelayedexpansion
d:
cd \programs\batch
for /f %%i IN (MachineList.txt) do (
echo %%i
call :worker %%i
)
endlocal

:worker
nbtstat -a %1 | find "<1E> GROUP"
if !ERRORLEVEL! NEQ 0 goto F

dir \\%1\Admin$\explorer.exe /b
if !ERRORLEVEL! NEQ 0 goto X

freedisk /S %1 /D c: 10MB
if !ERRORLEVEL! NEQ 0 goto N
echo %1 found>>foundlog.txt
goto L
:F
echo F
goto L
:X
echo X
goto L
:N
echo N
:L
Echo L
goto :EOF

This doesn't:

@echo off
setlocal enableextensions enabledelayedexpansion
d:
cd \programs\batch
for /f %%i IN (MachineList.txt) do (
echo %%i
nbtstat -a %1 | find "<1E> GROUP"
if !ERRORLEVEL! NEQ 0 goto F

dir \\%1\Admin$\explorer.exe /b
if !ERRORLEVEL! NEQ 0 goto X

freedisk /S %1 /D c: 10MB
if !ERRORLEVEL! NEQ 0 goto N
echo %1 found>>foundlog.txt
goto L
:F
echo F
goto L
:X
echo X
goto L
:N
echo N
:L
Echo L
)
endlocal


The labels are only stubs, something useful will be there soon, now that I
have the basic logic working. The only thing I don't know at this point is
if the set local carries over through the call. I don't seem to need it, but
I don't like to use code I don't understand.

HHH
 
HipHopHank said:
The code I was having a problem with invoved several labels and the goto
command. All the labels and the goto's were within the parens, but they just
seemed to make the command processor nuts. The best I could do was get a
single pass through the for loop and then the program stopped. I don't know
at this point if it is the 'FOR' command or the Parens that had the problem.
I solved it by using the call command to call a label within the file. That
is working fine.

This works:
But there are flaws.

In a batch you've to take care yourself that a called routine is seperated
from normal flow.
@echo off
setlocal enableextensions enabledelayedexpansion
d:
cd \programs\batch
for /f %%i IN (MachineList.txt) do (
echo %%i
call :worker %%i
)
endlocal
The endlocal is implied when terminating the batch and and resets path
and variables to the state when setlocal was issued. Here is a missing:

goto :eof
:worker
nbtstat -a %1 | find "<1E> GROUP"
if !ERRORLEVEL! NEQ 0 goto F
The usage of delayed expansion isn't neccessary.

You could use conditional execution || or && to control flow as an
alternative.
dir \\%1\Admin$\explorer.exe /b
if !ERRORLEVEL! NEQ 0 goto X

freedisk /S %1 /D c: 10MB
if !ERRORLEVEL! NEQ 0 goto N
echo %1 found>>foundlog.txt
goto L
:F
echo F
goto L
:X
echo X
goto L
:N
echo N
:L
Echo L
goto :EOF

The :eof doesn't need to be defined, it is implied.
This doesn't:
The labels are only stubs, something useful will be there soon, now that I
have the basic logic working. The only thing I don't know at this point is
if the set local carries over through the call. I don't seem to need it, but
I don't like to use code I don't understand.
This batch should do the same as your sample. Readability is a matter
of personal preferrence - I like it more compact.

@echo off&setlocal EnableExtensions EnableDelayedExpansion
cd /D d:\programs\batch
for /f %%A IN (MachineList.txt) do echo %%A&call :worker %%A
goto :eof
:worker
nbtstat -a %1 |find "<1E> GROUP"||(echo f &exit /b 1)
dir \\%1\Admin$\explorer.exe /b ||(echo X & exit /b 2)
freedisk /S %1 /D c: 10MB ||(echo N & exit /b 3)
echo %1 found>>foundlog.txt

My uasge of exit /b errorlevel allows a sub or batch to pass information
to the caller. (Though not acted upon here)

HTH
 
Back
Top