Newly discovered pipe behavior - and a fun challenge!
Posted: 15 Aug 2019 12:20
Over at https://stackoverflow.com/a/57492041/1012053 jeb deduced a newly discovered behavior of Windows pipes.
We had all thought that each side of a pipe is always executed in a new cmd.exe process via CMD /S /D /C. Well it turns out cmd.exe is only used if the command is an internal command, or if the command is enclosed within parentheses. External commands that are not enclosed in parentheses are launched in a new process without invoking cmd.exe.
test.txt
test.bat
Output of test.bat
Here is the challenge:
So I thought it would be fun to further probe / prove the behavior via %CMDCMDLINE%. Boy was I surprised by how quickly the results can become insanely complicated.
Tests 1 - 8 are all trivial and easy to trace. But my jaw dropped when I saw the results of 9, 10, and 11. The output for test 11 is 907 bytes
I have yet to take the time to trace the logic of the last three tests.
Dave Benham
We had all thought that each side of a pipe is always executed in a new cmd.exe process via CMD /S /D /C. Well it turns out cmd.exe is only used if the command is an internal command, or if the command is enclosed within parentheses. External commands that are not enclosed in parentheses are launched in a new process without invoking cmd.exe.
test.txt
Code: Select all
%var%
OK
&
Code: Select all
@echo off
setlocal
set "var=OK"
<nul set /p "=test 1: " & break | echo %%var%%
<nul set /p "=test 2: " & break | findstr %%var%% test.txt
<nul set /p "=test 3: " & break | (findstr %%var%% test.txt)
<nul set /p "=test 4: " & break | findstr ^& test.txt
<nul set /p "=test 5: " & break | (findstr ^^^& test.txt)
Code: Select all
test 1: OK
test 2: %var%
test 3: OK
test 4: &
test 5: &
Here is the challenge:
So I thought it would be fun to further probe / prove the behavior via %CMDCMDLINE%. Boy was I surprised by how quickly the results can become insanely complicated.
Code: Select all
@echo off
echo(&echo 1) break ^| cmd /v:on /c echo %%%%cmdcmdline%%%%
break | cmd /v:on /c echo %%cmdcmdline%%
echo(&echo 2) break ^| cmd /v:on /c echo !cmdcmdline!
break | cmd /v:on /c echo !cmdcmdline!
echo(&echo 3) break ^| cmd /v:on /c echo %%%%cmdcmdline%% %%%%cmdcmdline%%%%
break | cmd /v:on /c echo %%cmdcmdline%% %%cmdcmdline%%
echo(&echo 4) break ^| cmd /v:on /c echo !cmdcmdline! !cmdcmdline!
break | cmd /v:on /c echo !cmdcmdline! !cmdcmdline!
echo(&echo 5) break ^| cmd /v:on /c echo %%%%cmdcmdline%%%% !cmdcmdline!
break | cmd /v:on /c echo %%cmdcmdline%% !cmdcmdline!
echo(&echo 6) break ^| (cmd /v:on /c echo !cmdcmdline!)
break | (cmd /v:on /c echo !cmdcmdline!)
echo(&echo 7) break ^| (cmd /v:on /c echo %%%%cmdcmdline%%%%)
break | (cmd /v:on /c echo %%cmdcmdline%%)
echo(&echo 8) break ^| (cmd /v:on /c echo !cmdcmdline! !cmdcmdline!)
break | (cmd /v:on /c echo !cmdcmdline! !cmdcmdline!)
echo(&echo 9) break ^| (cmd /v:on /c echo %%%%cmdcmdline%%%% %%%%^^^^cmdcmdline%%%%)
break | (cmd /v:on /c echo %%cmdcmdline%% %%^^cmdcmdline%%)
echo(&echo 10) break ^| (cmd /v:on /c echo %%%%cmdcmdline%%%% !cmdcmdline!)
break | (cmd /v:on /c echo %%cmdcmdline%% !cmdcmdline!)
echo(&echo 11) break ^| (cmd /v:on /c echo %%%%cmdcmdline%%%% %%%%cmdcmdline%%%%)
break | (cmd /v:on /c echo %%cmdcmdline%% %%cmdcmdline%%)
I have yet to take the time to trace the logic of the last three tests.
Code: Select all
1) break | cmd /v:on /c echo %%cmdcmdline%%
cmd /v:on /c echo %cmdcmdline%
2) break | cmd /v:on /c echo !cmdcmdline!
cmd /v:on /c echo !cmdcmdline!
3) break | cmd /v:on /c echo %%cmdcmdline% %%cmdcmdline%%
cmd /v:on /c echo %cmdcmdline% %cmdcmdline% cmd /v:on /c echo %cmdcmdline% %cmdcmdline%
4) break | cmd /v:on /c echo !cmdcmdline! !cmdcmdline!
cmd /v:on /c echo !cmdcmdline! !cmdcmdline! cmd /v:on /c echo !cmdcmdline! !cmdcmdline!
5) break | cmd /v:on /c echo %%cmdcmdline%% !cmdcmdline!
cmd /v:on /c echo %cmdcmdline% cmd /v:on /c echo %cmdcmdline% !cmdcmdline! cmd /v:on /c echo %cmdcmdline% !cmdcmdline!
6) break | (cmd /v:on /c echo !cmdcmdline!)
cmd /v:on /c echo !cmdcmdline!
7) break | (cmd /v:on /c echo %%cmdcmdline%%)
C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% )" )"
8) break | (cmd /v:on /c echo !cmdcmdline! !cmdcmdline!)
cmd /v:on /c echo !cmdcmdline! !cmdcmdline! cmd /v:on /c echo !cmdcmdline! !cmdcmdline!
9) break | (cmd /v:on /c echo %%cmdcmdline%% %%^^cmdcmdline%%)
C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" %cmdcmdline% %^cmdcmdline% )" cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %^cmdcmdline% )" %cmdcmdline%
10) break | (cmd /v:on /c echo %%cmdcmdline%% !cmdcmdline!)
C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% !cmdcmdline! )" !cmdcmdline! )" cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% !cmdcmdline! )" !cmdcmdline! cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% !cmdcmdline! )" !cmdcmdline! )" cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% !cmdcmdline! )" !cmdcmdline!
11) break | (cmd /v:on /c echo %%cmdcmdline%% %%cmdcmdline%%)
C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" )" C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" cmd /v:on /c echo C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" C:\WINDOWS\system32\cmd.exe /S /D /c" ( cmd /v:on /c echo %cmdcmdline% %cmdcmdline% )" )"
Dave Benham