I have test1.bat, test2.bat, test3.bat with this exact below content:
echo %0
I have test.bat thus:
test1.bat > t1 && test2.bat > t2 && test3.bat > t3
echo done with test?.bat invocation
set /p t1=<t1
set /p t2=<t2
set /p t3=<t3
del t1 t2 r3
echo %t1% %t2% %t3%
echo done
This results in none of the echo statements being displayed, however, the files t1, t2 and t3 get created. They are not deleted.
CodePudding user response:
This works:
test1.bat > t1 && test2.bat > t2 && test3.bat > t3
when changed to
call test1.bat > t1 && call test2.bat > t2 && call test3.bat > t3
Though, I am not sure why the call statement is really necessary. I guess I have a second question, as to what happens when I don't use the call statement?
CodePudding user response:
Unless you use call
to run another batch file, execution control does not return to the calling batch file when the called one has finished. This explains why the subsequent commands of your script are not executed.
Your situation is a little bit tricky since you are running multiple batch files from a single command line:
test1.bat > t1 && test2.bat > t2 && test3.bat > t3
Now when a batch file is executed, it is not stored in memory as a whole, rather each line is read from the batch file and then buffered. During parsing, one of the first things is tokenisation and redirection handling, where &&
and >
become recognised1.
As you seem to be aware, the &&
operator lets the following command execute only if the preceding one succeeds, meaning its exit code is zero.
Now the full buffered line becomes executed, but since execution control does not return to the caller due to the lack of call
, also the exit codes of the callees are not reported back, hence all three sub-scripts will be run one after another unconditionally.
Experiment
The following experiment illustrates what is claimed above.
Put into each test?.bat
file just a single command @exit /B #
with the #
replaced by the number from the file name ?
minus one (so test1.bat
contains @exit /B 0
, for instance).
Then execute:
test1.bat > t1 && test2.bat > t2 && test3.bat > t3
There will be three files t1
, 2
and t3
, the returned exit codes are not recognised.
Now execute:
call test1.bat > t1 && call test2.bat > t2 && call test3.bat > t3
There will be only two files t1
and t2
, the returned exit codes are indeed recognised.
1) Refer to this comprehensive thread for details: How does the Windows Command Interpreter (CMD.EXE) parse scripts?