node.jspowershelljob-control

How can I suppress “Terminate batch job (Y/N)” confirmation in PowerShell?


When I press run popular node command line apps (like gulp) and 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?


Solution

  • tl;dr


    Background information on the Terminate batch job (Y/N)? prompt, which applies to [CLI entry points that are implemented as] batch files:

    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.

    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:


    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:

    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.


    [1] To determine which Node.js version shipped with which npm version, see this answer.