Reputation: 46496
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?
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.
I know how to fix this. Either (or both) of:
||
and &&
should be paired with call
.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.
Upvotes: 1
Views: 105
Reputation: 82192
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.bat
one.bat
@two.cmd && echo success || echo fail
echo This line will never be reached
Or add a call to a label
one.bat
@two.cmd && echo success || echo fail & call :myLabel
echo This line will never be reached
:myLabel
echo This line will never be reached
Invalid attempt to call a jump target outside a batch file.
The cause for seeing the success
or fail
messages 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.
Upvotes: 0