I suppose you tested different things.
I retested it on Win7x64
Code: Select all
for /F %%i in ("") do echo empty | more
echo 1. Works
(for /F %%i in ("") do echo empty) | more
echo 2. Works
(for /F %%i in ('type nul') do echo empty) | more
echo 3. Works
for %%a in () do echo empty | more
echo 4. Works
timeout /t 2
(for %%a in () do echo empty) | more
echo 5. Crashes
Only sample #5 crashes.
I expect the same results on any Windows version.
Where is the problem?
First I tried to examine it with the cmdcmdline trick, but it crashes always when the EMPTY-FOR is present, independent if the code would be executed at all.
Code: Select all
(
call showCmdCmdLine.bat
exit
for %%a in () do echo CRASH WITHOUT EXECUTION
) | more
It crashes, even when the FOR loop will be REMarked
(SET LF=^
%=EMPTY=%
)
set "XREM=REM "
(
call showCmdCmdLine.bat
%%XREM%% for %%a in () do echo empty ^%%LF%%%%LF%% echo After comment
) | more
The problem isn't the execution of the block, it's crashes while preparing for starting the new cmd.exe instance.
I tested it with
Code: Select all
echo dummy > log1.log | (for %%a in () do echo empty) | echo dummy > log2.log
In this case only log1.log will be created, the second cmd.exe instance will never be invoked.
But how to get an empty "standard" FOR-LOOP to work?
It's obvious The parser needs
a none empty expression that
is empty Code: Select all
( for %%a in (%%__CD__:~0^,0%%) do echo empty ) | more
The invoked cmd instance will be called with:
cmdcmdline: C:\Windows\system32\cmd.exe /S /D /c" ( FOR %a in (%__CD__:~0,0%) do echo empty )"
And as long as __CD__ exists, then zero characters from the front are in the most cases empty.