Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a non-interactive batch script think I've pressed control-C?

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?

like image 770
Harry Johnston Avatar asked Aug 22 '14 10:08

Harry Johnston


People also ask

How Use Ctrl C in batch file?

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

What does 0 |% 0 Do in batch?

%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).

What does %% mean in batch script?

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.

How to terminate batch job in cmd?

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.


1 Answers

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)?
like image 116
Harry Johnston Avatar answered Oct 11 '22 12:10

Harry Johnston