233

In cmd, when we press Ctrl+C we get the target application terminated but if the target application is called from a batch file, we get this "Terminate batch job (Y/N)" confirmation. I can never remember an instance where I chose not to terminate the batch job. How can we skip this confirmation?

Srikanth
  • 5,219

18 Answers18

86

At this site, I found an effective solution:

script2.cmd < nul

To not have to type this out every time I made a second script called script.cmd in the same folder with the line above. I've tested this technique on XP only, but others have confirmed it on Win 7.

Nathan adds: another option is to put the following code at the top of script.cmd which does the same thing in one file:

rem Bypass "Terminate Batch Job" prompt.
if "%~1"=="-FIXED_CTRL_C" (
   REM Remove the -FIXED_CTRL_C parameter
   SHIFT
) ELSE (
   REM Run the batch with <NUL and -FIXED_CTRL_C
   CALL <NUL %0 -FIXED_CTRL_C %*
   GOTO :EOF
)
Gringo Suave
  • 1,394
80

AFAIK you can't as this behavior is by design and controlled by the command interpreter. There is no method of "mapping" or even "intercepting" this unless you de-compile and recompile the interpreter directly.

BinaryMisfit
  • 20,879
78

Press Ctrl+C twice.

53

Install Clink and change the terminate_autoanswer setting by running this on your prompt:

clink set cmd.auto_answer answer_yes
Value Meaning
off Turns off auto answer
answer_yes Answer with 'Y' when prompted after Ctrl+C
answer_no Answer with 'N' when prompted after Ctrl+C

Alternatively, on old versions of clink, this can be done via the settings file should be here: C:\Users\<username>\AppData\Local\clink\settings.

    # name: Auto-answer terminate prompt
    # type: enum
    # Automatically answers cmd.exe's 'Terminate batch job (Y/N)?' prompts. 0 =
    # disabled, 1 = answer 'Y', 2 = answer 'N'.
    terminate_autoanswer = 1

This then "just works" with any cmd.exe window. You don't need to alter what's running or otherwise, since clink piggy-backs on cmd.exe. 1

Frickin' awesome, IMO!


1 But you will need to close and reopen cmd.exe before it takes effect.
2 Original unmaintained CLink repo here: http://mridgers.github.io/clink/

MC78
  • 103
Macke
  • 1,253
21

If you don't need to do anything in the batch file after your application finishes normally, then using the start command ensures that the batch file is already finished by the time you press Ctrl-C. And hence the message will not appear.

For example:

@echo off

set my_command=ping.exe
set my_params=-t www.google.com

echo Command to be executed by 'start': %my_command% %my_params%

:: When NOT using /B or /WAIT then this will create a new window, while
:: execution of this very batch file will continue in the current window:

start %my_command% %my_params%

echo.
echo This line will be executed BEFORE 'start' is even finished. So, this
echo batch file will complete BEFORE one presses Ctrl-C in the other window.
echo.

:: Just for testing use 'pause' to show "Press any key to continue", to see
:: the output of the 'echo' commands. Be sure to press Ctrl-C in the window
:: that runs the 'ping' command (not in this very window). Or simply remove
:: the next line when confused:

pause

(Tested on Windows XP.)

Arjan
  • 31,511
sgmoore
  • 6,599
15

I've been fighting with this desire to avoid the "Terminate batch job" prompt for a little while.

My latest epiphany is a bit of a sleight of hand (or console window), by replacing one instance of cmd.exe with another. This is accomplished by executing the command/program via start cmd /k followed immediately by exit in the .BAT file.

The original console window disappears and the replacement one can be stopped cleanly via Ctrl-C.

Consider the following example of a traceroute that can be interrupted by Ctrl+C, or allowed to complete, returning the user to the C:\> prompt:

@echo off

set timeout=100
if not "%2"=="" set timeout=%2

start cmd /k tracert -w %timeout% %1
exit

The environment substitution of a new command interpreter may not be for everyone, but, to the naked eye, looks and works well for me.

mklement0
  • 2,148
ViperGeek
  • 398
13

Gringo's solution is good, but doesn't work well with scripts which pass along the argument list (i.e. python myscript.py %*), since SHIFT doesn't update %*. There are workarounds, but they have certain limitations.

Here's the modification I ended up with:

IF [%JUSTTERMINATE%] == [OKAY] (
    SET JUSTTERMINATE=
    python myscript.py %*
) ELSE (
    SET JUSTTERMINATE=OKAY
    CALL %0 %* <NUL
)

99.(9)% flawless.

Alec Mev
  • 659
8

TCC/LE, which is a free CMD replacement (think of it as CMD++), has an option to suppress the terminate batch job prompt. You can find the option in the TCC Startup Configuration Dialog:

Cancel Batch File on Ctrl-C: Cancel batch file processing without the usual prompt when you press Control-C.

Screenshot:

TCC/LE options

If you've never heard of TCC/LE before, here's some blurb from the site:

TCC/LE is a replacement for the CMD command line (the default Windows command prompt). TCC/LE is a superset of CMD, with 111 internal commands (CMD has fewer than 40), 240 internal variables and functions, and hundreds of enhancements to existing CMD commands.

TCC/LE works with your existing command line applications and batch files, but offers major improvements in command line and batch file capabilities, and adds thousands of new features to your command prompt windows.

I used TCC/LE for years and 4NT before it. I've got a lot of love for it and can recommend it. Only reason I don't still use it is because I almost exclusively use PowerShell now.

Charles Roper
  • 10,879
5

See this Stack Overflow question.

However, patching cmd.exe is not something I would do for that.

Joey
  • 41,098
3

Solution using AutoHotkey

  1. Download and install AutoHotkey

  2. Create a script (e.g. terminate.ahk)

  3. Paste the following script

#SingleInstance Force

#IfWinActive ahk_exe cmd.exe ^d::terminate()

#IfWinActive ahk_exe powershell.exe ^d::terminate()

terminate() { SendInput {Ctrl down}c{Ctrl up} Sleep 100 SendInput y{Enter} }

  1. Execute the script

Now when you press Ctrl+D in powershell.exe or cmd.exe a Ctrl+C y Enter sequence is sent and that terminates the program.

If want to customize the hotkey, see List of Keys

If you want to apply this hotkey to another program, just add this to the script (e.g. Visual Studio Code -> code.exe):

#IfWinActive ahk_exe code.exe
^d::terminate()

The program name can be found at Task Manager > Details

Marcos
  • 329
1

Easiest way to suppress the confirmation if you use the Hyper terminal, is to add the hyper-yes plugin.

1

I don't know your context. It is really helpful if you can tell how you launch the application (by start or directly the path). If you can translate the batch script into one PowerShell script, then pwsh -f script_file may help you.

I read this QA when I tried use msys2 in Windows terminal. In Windows terminal, we can use pwsh -c "$env:MSYSTEM='UCRT64';$env:CHERE_INVOKING='enabled_from_arguments';D:\msys64\usr\bin\bash -l" to function as D:\msys64\msys2_shell.cmd -defterm -here -no-start -ucrt64 -shell bash (This translation needs a bit reading of the batch script). So we don't need the batch script then.


Notice we don't use -NoExit for pwsh which is one default parameter for "Developer PowerShell for VS 2022" in Windows terminal, so I guessed maybe also one similar parameter for start which is used by msys2_shell.cmd when not using -no-start. And by reading its doc in ss64, we can use /B option which is also said by Arjan's commment and Nick Bolton's. So start /B bash -l !SHELL_ARGS! will also work.

An5Drama
  • 181
0

I ran into this with an EXE that seemed to throw ^C to the parent batch on exit, causing the "Terminate Batch Job" prompt even on a clean exit.

The solution I chose to use was running the batch with "Start", similar to other answers, but from a PowerShell prompt (or via the PowerShell interpreter method from CMD, if you choose).

It's 2018 now, and in Windows 10 Microsoft has begun to supplant CMD with PowerShell as the preferred command prompt, so it's readily available in the GUI, by default.

Start is an alias for Start-Process.

When run, it just launches and returns. So when you stop the launched process, there is no "Terminate Batch Job" prompt.

By default it doesn't wait, so no additional arguments beyond the command and it's arguments are required.

Using start mything.exe -mythings -arguments in my batch worked perfectly.

In PowerShell scripts must be preceded by their path to be launched, so I run my batch file as .\host.bat.

0

A prime reason to suppress the "Terminate batch job (Y/N)", is to run a program in a loop (eg: re-run in case it crashes).

This https://stackoverflow.com/a/8185270/1170023 helped lead to this solution:

@ECHO OFF
rem assumes you have installed pslist from sysinternals to windows PATH

:RUN
echo Starting GoldenEye Dedicated Server
start "" srcds.exe -console -game gesource +maxplayers 16 +map ge_complex

:LOOP
pslist srcds >nul 2>&1
if ERRORLEVEL 1 (
  goto RUN
) else (
  rem echo Dedicated server is still running
  timeout /t 5 >nul
  goto LOOP
)
Kevin
  • 1,443
0

Just-found-in-2025 solution that works with most wrapped .exe-s: just add a || CALL IF EnsureError after .exe launch.

This makes cmd forget the earlier interruption, so no "Terminate batch job" question. Non-zero errorlevel is kept

The core idea behind this is the following finding: executing CALL <anything> in the same line or ()-expression just ignores the termination request caused by the command preceding that call. So adding || CALL IF EnsureError suppresses the "Terminate batch job" question, keeping a non-zero errorlevel since CALL IF EnsureError is a silent-but-not-valid command.

Here is a full working example where a wrapper.bat is a launcher-wrapper to some external .exe (powershell.exe is just a sample, I used it with python.exe too, shouldn't matter except the caveat below). Scroll right too see the main addition:

@powershell.exe "$DelayinSeconds = Read-Host -Prompt 'Enter how manys seconds to sleep'; start-sleep -Seconds $DelayinSeconds" || CALL IF EnsureError
@IF ERRORLEVEL 1 (ECHO Wrapped exe failed or interrupted, exiting batch & EXIT /B 1)
@ECHO Ok, continuing batch

Caveat: if the .exe return code would be 0 on interrupting the application, CMD would not execute the part after || so the "Terminate batch job" message would appear. This behavior actually depends on the .exe. If "always continue" is OK for a specific use case (for example that's end of script anyway) you can use &CALL IF EnsureError unconditional suppression method.

This caveat may be illustrated by the above example with powershell.exe:

Scenario Result
Type 5 when asked number, Enter, wait continuing batch message
Type x when asked number, Enter conversion error, non-zero errorlevel from .exe, exiting batch message
Press Ctrl+C when asked number non-zero errorlevel from .exe, exiting batch message
Press Ctrl+Break when asked number non-zero errorlevel from .exe, exiting batch message
Type 5 when asked number, Enter,
Press Ctrl+C while waiting
non-zero errorlevel from .exe, exiting batch message
Type 5 when asked number, Enter,
Press Ctrl+Break while waiting
Caveat: .exe does not exit immediately, and gives zero errorlevel after waiting
Terminate batch job (Y/N)? appears
0

Simply redirect the batch stdin to null by adding < nul to the end of the command.

0

In my case it was the ping.bat file that was right in my user directory (C:\Users\ in Vista or C:\Documents and Settings\ in XP) that was holding the batch job indeterminately.

This batch file was executed whenever I ran ping from the command prompt where the current directory is my user directory. Ping-ing from the Run window, or from other user's directory was running well.

Removed the file from my user dir and the problem was resolved!

-4

At the end of your script, just add the following command:

echo

This will not "damage" the behavior of your script, and it seems to prevent CMD to ask if you want to termininate the batch.

Star
  • 3
Henri
  • 1