So my batch script is ticking along nicely when suddenly this appears in the output log:
21:27:13.99 c:\apps\w7lab-scripting>some-command
Error 3221225786
^CTerminate batch job (Y/N)?
and the script stops dead.
The batch script is running in session zero, so I know it didn't receive a real control-C, and none of my code calls GenerateConsoleCtrlEvent
so that can't be it. The only clue is that some-command
was communicating with an interactive application at the time, and that application's console received a control-C. The expected behaviour was for some-command
to display the other application's exit code, then exit with the same code. The batch script would have dealt with the error appropriately, if it hadn't stopped dead.
What's going on here?
(1) (ConTRoL-C) In a Windows PC, holding down the Ctrl key and pressing the C key copies the currently highlighted object. The Mac equivalent is Command-C. See Ctrl-V. (2) (ConTRoL-C) In a Windows PC, holding down the Ctrl key and pressing the C key cancels the running program or batch file.
%0|%0 is a fork bomb. It will spawn another process using a pipe | which runs a copy of the same program asynchronously. This hogs the CPU and memory, slowing down the system to a near-halt (or even crash the system).
Use double percent signs ( %% ) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %a, %b, or %c. ( <set> ) Required. Specifies one or more files, directories, or text strings, or a range of values on which to run the command.
If you do not explicitly control the invocation of the target executable, you're out of luck (unless you're willing to install third-party cmd.exe replacements) and must press Ctrl+C twice in order to terminate execution.
The magic here is in exit code 3221225786, aka 0xC000013A or STATUS_CONTROL_C_EXIT.
The interactive application received a control-C, and didn't catch it, so as expected, it was aborted with STATUS_CONTROL_C_EXIT. The some-command
application correctly reported this as the remote application's exit code, and passed it back to the batch script.
What I hadn't realized was that cmd.exe
detects control-C in a batch script in exactly this way, by checking whether a child process returns STATUS_CONTROL_C_EXIT. So by returning this error code I was inadvertently stopping the batch script.
This can be demonstrated with a simple batch script:
cmd /c exit 3221225786
echo hello
which, when run, produces
C:\working\test>cmd /c exit 3221225786
^CTerminate batch job (Y/N)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With