So here I confess, not without a certain sense of pride: Sometimes I boldly go
where few programmers like to go - and then I write a few lines in DOS batch language.
Most of the time, it's not as bad as many people think. Its bad reputation
mostly stems from the days of DOS and Windows 95, but since the
advent of Windows NT, the command processor has learnt quite a few new tricks.
While its syntax remains absurd enough to drive some programmers out of their
profession, you can now actually accomplish most typical scripting tasks with it.
In particular, the
for statement
is quite powerful.
Anyway - a while ago, one of my batchfiles started to act up. The error message
was "The system cannot find the batch label specified - copyfile".
The batch file in question had a structure like this:
@echo off
rem copy all pdb files in the current directory into a backup directory
set pdbdir=c:\temp\pdbfiles
for /r %%c in (*.pdb) do call :copyfile "%%c" %pdbdir%
if errorlevel 1 echo Error occurred while copying pdb files
echo All pdb files copied.
goto :eof
rem copyfile subroutine
:copyfile
echo Copying %1 to %2...
copy /Y %1 %2 >nul
goto :eof
I know what you're thinking - no, this is
not the problem. This
is how you write
subroutines in DOS batch files. Seriously. And yes, the above script can
of course be replaced by a single
copy
command. The original script couldn't;
it performed a few extra checks for each and every file to be copied in
the
:copyfile
subroutine, but it also contained a lot of extra fluff which
distracts from the actual problem, so what you're seeing here is a stripped-down
version.
The error message complained that the label
copyfile
could not be found. Funny,
because the label is of course there. (The leading colon identifies it as a label.)
And in fact, the very same subroutine could be called just fine from elsewhere in
the same batch file!
For debugging, I removed the
@echo off
statement so that the command processor
would log all commands it executes; this usually helps to find most batch file
problems. But not this one - removing the
echo
"fixed" the bug. I added the
statement again - now I got the error again. Removed the
echo
statement - all is
fine.
Oh great. It's a
Heisenbug.
So I added the
echo
statement back in again and stared at the script hoping to find the
problem by the old-fashioned method of "flash of inspiration".
No inspiration in sight, though. Not knowing what to do, I added a few
empty
lines between the
for
and the
if errorlevel
statement and ran the script
again - no error message! Many attempts later, I concluded that it's
the sheer length of the script file which made the difference between
smooth sailing and desperation. By the way, the above demo script works
just fine, of course, because I stripped it down for publication.
Google confirmed my suspicion: Apparently, there are cases where
labels cannot be found even though they are most certainly in the batch file.
Maybe the length of the label names matters -
Microsoft Knowledge Base Article 63071
suggests that only the first eight characters of the label are significant.
However,
copyfile
has exactly eight characters!
I still haven't solved this puzzle. If you're a seasoned batch file
programmer sent to this place by Google and can shed some light on this,
I could finally trust that script again...
--
ClausBrod - 27 Jan 2006
Thanks a lot, Reinder!
--
ClausBrod - 05 Apr 2015
From
http://help.wugnet.com/windows/system-find-batch-label-ftopict615555.html, I tentatively conclude that
you need two preconditions for this to hit you:
- the batch file must not use CRLF line endings
- the label you jump to must span a block boundary
As to your remark "And in fact, the very same subroutine could be called just fine from elsewhere in the same batch file": in my experience, the subroutine gets called just fine when you get this error.
Regards,
Reinder
-- Reinder - 20 Jun 2008