2

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.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
gk_2000
  • 194
  • 3
  • 16

2 Answers2

1

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?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
0

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?

Gerhard
  • 22,678
  • 7
  • 27
  • 43
gk_2000
  • 194
  • 3
  • 16
  • 5
    If you just execute another batchfile, you transfer control to it - and control will never come back to the executing instance. If you `call` a batchfile, it will be executed and control will be transferred back to the calling instance, once the called batch file ends. – Stephan Dec 02 '21 at 20:22
  • So when I don't use the call statement, how come all three files get created? It should do the first call and never come back – gk_2000 Dec 02 '21 at 20:28
  • In this case you do not need to use `&&`. `&&` is conditional upon the previous call command not returning an error, as your batch files do not contain any code which could return an error, you do not need that conditional statement. For that reason just use `&`. – Compo Dec 02 '21 at 20:31
  • @Compo I do have a use case that requires the &&. I have pared it all down so that the essential components of the problem are preserved but details removed. – gk_2000 Dec 02 '21 at 20:33
  • Well you should for readability parenthesize, `"command1" 1>"output1" 2>NUL && ("command2" 1>"output2" 2>NUL && ("command3" 1>"output3" 2>NUL))`. – Compo Dec 02 '21 at 20:38
  • 3
    @gk_2000, I've just read the information that has been removed, _(edited out)_, by another member. I have to say however, that I do not have any issue with their edit, and would myself have done the same. Please do not question downvotes, unless the person who downvotes specifically comments to tell you why they have done so. Please also do not ask people to upvote. – Compo Dec 02 '21 at 20:43
  • 3
    Well I would have to read Dave and Jeb's great Q&A on [How does the Windows Command Interpreter (CMD.EXE) parse scripts?](https://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts) but it seems logical that since all lines of code are interpreted before execution that the file streams are all opened at the time the line of code is executed. So all the files get created when the line of code starts to execute. – Squashman Dec 02 '21 at 20:49
  • 2
    all three `test?.bat` get executed, because the parser already has them "in memory" (they are on one line), but the last one ends without returning the control to the main script. – Stephan Dec 02 '21 at 20:50
  • 2
    And I agree with @Compo, you should have never added that ending paragraph to your question. It is not needed nor provides any relevance to the question. – Squashman Dec 02 '21 at 20:50