Search code examples
windowsbatch-filecmd

In this batch script, why doesn't control reach the echo statement?


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 t3
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.


Solution

  • 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?