44

When I press Ctrl+C in PowerShell, I receive:

Terminate batch job (Y/N)?

Similar to https://superuser.com/questions/35698/how-to-supress-terminate-batch-job-y-n-confirmation, except for Windows PowerShell.

Does PowerShell provide any more control over batch jobs than what CMD does?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • 4
    You shouldn't be getting that message unless you're running batch scripts from PowerShell. Those are launched as CMD child processes, hence they behave like any other CMD/batch process. – Ansgar Wiechers Aug 22 '16 at 19:23
  • 1
    FWIW, PowerShell can break into a running script if you press Ctrl-Pause(Break). – wOxxOm Aug 23 '16 at 09:24
  • See also [How to Disable Ctrl-C /Ctrl-S While Running a Batch File](http://serverfault.com/a/109715) – wOxxOm Aug 23 '16 at 09:50
  • 3
    If you run the node application with `npm start` the process is automatically wrapped into a CMD/batch process. Try to run the app directly with `node app.js` or whatever. – Davide Aversa Nov 06 '16 at 15:40
  • 1
    For a solution that works in Powershell using Autohotkey, see: https://superuser.com/a/1703017/351521 – Marcos Feb 03 '22 at 18:56
  • just an alternate for someone like me facing this issue with the vs-code terminal, do set the bash as the default terminal(bash doesn't show up that message), and that is it. Thanks, can refer: https://stackoverflow.com/questions/44435697/vscode-change-default-terminal – Wasit Shafi Mar 17 '23 at 17:46

5 Answers5

32

tl;dr

  • The cause of the problem is that gulp (and any other command that shows this message) is actually a batch file (*.cmd, *.bat) and the behavior is built into cmd.exe, the interpreter of batch files.

  • Package managers are increasingly providing PowerShell scripts (*.ps1) as well (see bottom section), which bypasses the problem when running from PowerShell.


The behavior is neither caused by PowerShell nor can PowerShell change it (as evidenced by the PowerShell source-code repo not containing the prompt message).

The behavior is built into cmd.exe - Powershell, in this case, is calling a .cmd file (batch file), which is interpreted by cmd.exe.

  • If you explicitly control the invocation of the target executable, you can fix this by moving to Powershell - note this has its own considerations, see below.

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

  • A[n ill-advised] workaround is to modify the cmd.exe binary - see article with instructions on how to patch the cmd.exe executable in order to suppress the prompt. Additionally, you can post a feature request on GitHub to request that this behavior be fixed at the source, though that is unlikely to happen for reasons of backward compatbility.

To demonstrate the behavior:

The examples assume that Node.js is installed and that node.exe is therefore in your PATH:

First, invoke node.exe directly, with a tight loop that requires you to press Ctrl+C to terminate the process.

PS> node -e "while (true);"

As you'll see, pressing Ctrl+C instantly terminates the process - no confirmation prompt.

Now, let's create a sample batch file that invokes the same command and invoke that batch file:

PS> "@echo off`nnode -e `"while (true);`"" | Set-Content test.cmd
PS> ./test.cmd

As you'll see, pressing Ctrl+C now presents the undesired Terminate batch job (Y/N)? prompt. (You'd get the same behavior if you ran the batch file from cmd.exe.)

To demonstrate that gulp is a .cmd (batch) file:

You say you're running your command via gulp's CLI.

On Windows, the entry point for the gulp CLI is gulp.cmd [see update in the bottom section] - i.e., a batch file. That is how it works in general for npm-package "binaries" (executables) implemented as either JS files or shell scripts.

That gulp invokes gulp.cmd can be verified as follows:

# Execute from a project folder that has `gulp` installed as a dependency.
# If `gulp` is installed *globally* 
# Note: CLI `npx` requires npm version 5.2.0+
PS C:\some\NodeJs\project> npx where gulp

You'll see something like:

C:\some\NodeJs\project\node_modules\.bin\gulp
C:\some\NodeJs\project\node_modules\.bin\gulp.cmd

Note that where.exe also lists the extension-less Unix-shell script, ...\gulp; however, from cmd.exe / Powershell such a shell script isn't directly executable, and it is ...\gulp.cmd - the batch file - that is executed.
(If in doubt, place a command such as @set /p dummy="Press a key" at the start of the gulp.cmd file, and you'll see that this command executes when you invoke gulp without the .cmd extension.
Also note that there is no gulp.exe.)

More generally, on Windows, a project's node_modules\.bin subfolder contains pairs of CLI entry points for the CLIs that come with packages that the project depends on locally:

  • node_modules\.bin\<some-cli> is the Unix shell script (whose executing interpreter is controlled via its shebang line).
  • node_modules\.bin\<some-cli>.cmd is the helper batch file for Windows.

Updates and future considerations:

In the context of npm modules, the problem would go away if a PowerShell script (*.ps1) were used as the helper script on Windows. There are tickets for npm, yarn and similar software to do this. There are also some drawbacks:

  • *.ps1 files aren't directly executable from outside of PowerShell, notably from cmd.exe and File Explorer (and changing that is nontrivial).

  • PowerShell still hasn't fully replaced cmd.exe as the default shell, as of Windows 10 (and won't anytime soon, if ever).

When called from PowerShell, a *.ps1 file would be found and run in-process, so a possible solution is for the npm project to also provide *.ps1 helper scripts, which would take precedence over *.cmd files of the same name.

  • Update:
    • Recent versions of npm (verified in 6.14.10) indeed DO install such *.ps1 files.
    • Alternative package manager yarn, since v2 does not seem to use batch files anymore at all, so the original problem is bypassed there; (v1, by contrast, still uses batch files (only); upgrading from v1 must be done on a per-project basis see the migration instructions).
mklement0
  • 382,024
  • 64
  • 607
  • 775
6

As the other answer notes, the correct fix is to replace cmd scripts with ps1 versions.

However another workaround for users of the Hyper shell is 'Hyper yes', a plugin that automatically hits y for you when the prompt comes up.

enter image description here

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
1

best way to avoid it is to not start it, in my case, is not to type npm run devStart but instead type nodemon ./server.js localhost 3000 here's how it looks like

Elvis Van
  • 11
  • 2
  • This does not explain why one command is a batch job and another isn't. The explanation is that one of the commands executes multiple commands in one line (like chaining with && for example), and the other doesn't. – Paul-Sebastian Manole Nov 13 '22 at 12:28
-1

Press Ctr-c again after the "Terminate batch job (Y/N)?"

As far back as thirteen years ago this was the third best answer (why third ?) at https://superuser.com/questions/35698/how-to-supress-terminate-batch-job-y-n-confirmation

(I just found it again while trying to eliminate this annoying message)

mstram
  • 584
  • 1
  • 6
  • 13
-2
@echo off
start /w "" "C:\myfile.bat" 2>nul|findstr /i "termin"

if errorlevel 1 goto bypass


:bypass

echo hello

timeout /t 5 >nul
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
STEXUP
  • 11