148

I'm running npm on Windows and would like to use & style parallel operations in run-scripts but running in parallel in cmd is kind of messy in my package.json file I'd like to write-

scripts: { "go": "cmd1 & cmd2"} 

but npm executes the script under cmd.exe which does not know about ; I could change this to scripts: { "go": "bats/bat1.bat") where bat1.bat is a cmd bat file that uses the windows style call or start commands to run commands in parallel. which works but gives me a script that only works on Windows.

It would be a lot simpler if I could get npm to run the script under a bash clone or cygwin.

I tried config: { "shell": "bash"} but that still ran cmd.exe

Is there any way to tell npm to run-scripts using a specific shell (not cmd.exe)?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
user2129444
  • 1,659
  • 2
  • 13
  • 7
  • 1
    Is it [still] not possible to specify a shell in package.json? I use npm for both windows and bash scripting and have no way of overriding the default "shell" or "script-shell" settings for a particular package.json? – Corey Alix Sep 13 '19 at 13:49

7 Answers7

330

Since npm 5.1

npm config set script-shell "C:\\Program Files (x86)\\git\\bin\\bash.exe"  

or (64bit installation)

npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"

Note that you need to have git for windows installed.

You can revert it by running:

npm config delete script-shell
Community
  • 1
  • 1
DuncanSungWKim
  • 3,774
  • 1
  • 14
  • 11
  • 12
    This should be the accepted answer! Works on Windows 10 with Git Bash (VS Code included). – TechAurelian Nov 09 '17 at 12:37
  • 10
    `npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"` is the answer to all my problems running parallel scripts on Windows 10 64-Bit. @DuncanSungWKim 감사합니다 for this. – TaeKwonJoe Mar 21 '18 at 18:20
  • Thanks , I had a problem with npm start that was working in cmd but not in bash and I ran the script you suggested and it worked!!!! After two days of googeling for an answer.... -_- Thanks for the help – Alon Samuel Jan 18 '19 at 23:58
  • 3
    If I am already in a git bash shell and run `npm run – JHH Jan 29 '19 at 10:30
  • 3
    @JHH - I also had shells opening from vscode because I was using git-bash.exe instead of bash.exe. When I fixed so vscode bash was the same as the script-shell bash, the issue was resolved. – Corey Alix Sep 11 '19 at 14:03
  • 2
    If you're unsure about the bash.exe path, you can just do `npm config set script-shell bash` since bash.exe location is probably in `PATH` – Psddp May 18 '20 at 02:18
  • How do you do this for cygwin? – Daniel Kaplan Aug 05 '20 at 00:38
  • Great advice - but be careful as this [doesn't play nice with **yarn**](https://github.com/yarnpkg/yarn/issues/5717) – KyleMit Jan 08 '21 at 21:55
37

Here's one way to do it:

  1. Create a script, such as my_script.sh, in your project bin directory.
  2. In your package.json file, add a line to run the script using bash. For example:

    "scripts": {
      "boogie": "bash bin/my_script.sh"
    }
    

Now you can run your bash script from npm by:

    npm run-script boogie

Not very elegant, but it works.

If you are developing in both Windows and Linux/Unix, then at least this approach is fairly portable to both environments.

Craig Johannsen
  • 679
  • 6
  • 6
20

Ideally, overriding the npm shell config parameter should work, but npm (at least version 1.4.14) seems in Windows to ignore the setting and use cmd.exe instead.

Use the following command in your bash or Git Bash shell to find out the shell setting:

$ npm config ls -l | grep shell

By default, the output will be:

shell = "C:\\WINDOWS\\system32\\cmd.exe"

However, to override the default shell parameter, you can add (or edit) an npmrc file to the \Users\yourusername\AppData\Roaming\npm\etc directory. Just add the following line:

shell = "C:\\Program Files (x86)\\git\\bin\\bash.exe"

The path you use can be any valid path to bash.exe. Now, if you run the above "npm config ls -l | grep shell" command, you will see the following output, indicating that the shell parameter has been overriden:

shell = "C:\\Program Files (x86)\\git\\bin\\bash.exe"
; shell = "C:\\WINDOWS\\system32\\cmd.exe" (overridden)

One day, perhaps, a new version of npm will pay attention to the overridden shell parameter.

Craig Johannsen
  • 679
  • 6
  • 6
  • 2
    Wish this worked. I changed the COMSPEC environment variable and it appears to be pulling from that, but I could not get it to work correctly. – cchamberlain Jun 10 '15 at 07:00
  • 4
    This do the same job: `$ npm config set shell "C:\\msys64\\usr\\bin\\bash"` – kwarnke Mar 29 '17 at 15:04
  • I solved my problem following your suggestion. Now, I'm able to run scripts on npm which contain more commands separated by `;` On Windows, in folder C:\Users\username\ I added a `.npmrc` file containing `shell = "C:\\Program Files\\Git\\bin\\bash.exe" script-shell = "C:\\Program Files\\Git\\bin\\bash.exe"` – iFederx Jul 29 '20 at 09:45
15

You can also use cross-platform powershell https://github.com/powershell/powershell#get-powershell for npm scripts.

To set for single project, run this from project root folder:

npm config set script-shell pwsh --userconfig ./.npmrc

To globally set for all node projects:

npm config set script-shell pwsh [--global]
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
4

just using CMD's way to run .bat!

.json
"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "app": "cd build & browser-sync start --server --files 'index.html'",
    "bat": "start start-browser.bat",
    "starts": "start http://localhost:7777/datas/ && start http://localhost:7777/Info/"
},
.bat
start http://localhost:7777/datas/ && start http://localhost:7777/Info/
Qwerty
  • 29,062
  • 22
  • 108
  • 136
1

Use a specifically created node_module for this purpose. I suggest using npm-run-all, but others exists, such as parallelshell.

Parallelshell example is below for drop-in-replacement for your question.

"scripts": {
    "parallelexample1": "parallelshell \"echo 1\" \"echo 2\" \"echo 3\""
},

following command:

npm run parallelexample1

works both on windows and unix(Linux/MacOS).

Interestingly npm-run-all does not support shell commands; therefore we need to put all shell commands to separate scripts like below.

"scripts": {
   "parallelexample2": "npm-run-all echo*",
    "echo1": "echo 1",
    "echo2": "echo 2",
    "echo3": "echo 3"
},

Following command:

npm run parallelexample2

works both on windows and unix(Linux/MacOS).

Atilla Ozgur
  • 14,339
  • 3
  • 49
  • 69
1

In my case I just needed to run npm start from inside Bash. I run cmd then I open bash by running "c:\Program Files\Git\bin\bash.exe". Under bash shell I then was able to call npm build and npm start succesfully.

You may already have bash if you are using Git. If not, you can install it.

Hope this may save someone's time.

Mike Keskinov
  • 11,614
  • 6
  • 59
  • 87