While trying to provide a comprehensive answer to the question Why is FindStr returning not-found, I encountered strange behaviour of code that involves a pipe. This is some code based on the original question (to be executed in a batch-file):
rem // Set variable `vData` to literally contain `...;%main%ProgramsGoBin`:
set "vData=...;%%main%%ProgramsGoBin"
set "main=C:Main"
echo/%vData%| findstr /I /C:"%%main%%\Programs\Go\Bin"
This does not return a match, hence nothing is echoed and ErrorLevel
becomes set to 1
.
Though when I go through the parsing process step by step, I conclude the opposite, I do expect a match and an ErrorLevel
of 0
, because:
at first, the whole line is parsed and immediate (%
) expansion takes place, hence %vData%
becomes expanded and %%
become replaced by %
, resulting in the following command line that is going to be executed:
echo/...;%main%ProgramsGoBin| findstr /I /C:"%main%\Programs\Go\Bin"
each side of the pipe |
is executed in its own new cmd
instance by cmd /S /D c
, both of which run in cmd
context (which affects handling of %
-expansion), resulting in these parts:
left side of the pipe:
echo/...;C:MainProgramsGoBin
right side of the pipe:
findstr /I /C:"C:Main\Programs\Go\Bin"
(the search string that findstr
finally uses is C:MainProgramsGoBin
as the
is used as escape character even in literal search mode, /C
or /L
)
As you can see the final search string actually occurs within the echoed string, therefore I expect a match, but the command lines does not return one. So what is going on here, what do I miss?
When I clear the variable main
before executing the pipe command line, I get the expected result, which leads me to the conclusion that the variable main
becomes not expanded despite my assumption above (note that in cmd
context, %main%
is kept literally when the variable is empty). Am I right?
It is getting even more confusing: when I put the right side of the pipe in between parentheses, a match is returned, independent on whether or not the variable main
is defined:
echo/%vData%| (findstr /I /C:"%%main%%\Programs\Go\Bin")
Can anyone explain this? Could this be connected to the fact that findstr
is an external command, opposed to echo
? (I mean, break | echo/%vData%
expands the value of main
as expected if defined...)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…