Suppose I have batch file one.cmd:
@two.cmd && echo success || echo fail
and two.cmd:
@exit /b 1
If I run this at an interactive CMD prompt it behaves one way:
D:\>one.cmd
success
But if I run it under cmd /c it behaves a different way:
D:\>cmd /c one.cmd
fail
Why is this?
Some other cases
PowerShell and Python's subprocess.run both give the same result as cmd /c.
cmd /k gives the same result as running interactively. Which I guess makes sense, given that it's a new interactive shell.
Why this matters
I know how to fix this. Either (or both) of:
- any use of
||and&&should be paired withcall. - always exit batch files with
cmd.exe /c exit %ERRORLEVEL%.
See more here: Why doesn't Windows batch file `exit` work with `||`?).
My real goal is to write a unit test to ensure that my batch file correctly propagates error on failure, but because the unit test is not using an interactive shell, it doesn't reproduce the problem.
Mofi already mentioned it in his comment: A batch/cmd file have to be called in a batch file.
The cause is, a CALL put a return point to the call stack, but without CALL there is no entry on the stack!
In your case, at first glance, there seems to be no difference, but try to add one more line to
one.batone.bat
Or add a call to a label
one.bat
The cause for seeing the
successorfailmessages is the fact, that a line or block will always be cached.It isn't a return to the code, it's simply the execution of the cache.