4

I am running Node 6.9.5 and NPM 3.10.10 on a Windows 7 machine. My terminal is Cygwin 2.877.

If I try to run the following in Cygwin, it works fine:

mkdir mydir/mysubdir;

However, if I put it into a package.json file instead, e.g.:

"scripts": {
 "test": "mkdir mydir/mysubdir"
},

and run:

npm run test

It fails with:

The syntax of the command is incorrect.

After Googling the above, it seems to be a Windows Command Prompt error, not a Cygwin one. As such, it seems that NPM is trying to run the script using the Command Prompt rather than the existing Cygwin environment.

How can I fix this? Or rather, how can I make sure NPM runs scripts in the terminal environment it is being invoked from?

csvan
  • 8,782
  • 12
  • 48
  • 91
  • Are you using a Win32 or Cygwin build of NPM? In general, you would want a cygwin build if you intend to interact with Cygwin tools or the Cygwin view of the file system. – cnettel Feb 08 '17 at 08:16
  • @cnettel I'm using the win32 build. Will see if using the Cygwin build changes anything. Is there no way to force npm to use a given shell environment though? – csvan Feb 08 '17 at 08:18
  • Turns out there isn't: https://github.com/npm/npm/issues/6543. The env on Windows is always `cmd.exe`. The recommended way is to write node scripts instead and run those, I will probably go down that road. – csvan Feb 08 '17 at 08:21
  • Possible duplicate of [Why does \`DEBUG=foo node index.js\` fails in \`scripts\` section of \`package.json\`](http://stackoverflow.com/questions/41379090/why-does-debug-foo-node-index-js-fails-in-scripts-section-of-package-json) – rsp Feb 08 '17 at 08:31
  • Just as a note, you can sometimes get slightly better Cygwin-like behavior by adding the Cygwin binaries in the (Windows) PATH. I've done the same in cases where I wanted to use the Win32 Python or Perl, but I also needed some cygwin tool. A single Cygwin binary launched from a cmd prompt will frequently behave quite OK. The main problem is that the calling process will still not have the same view of the file system. Advanced piping and modification of environment variables will also not work, but just to call out to a specific extenral tool, it can be OK. Not of much relevance in this case. – cnettel Feb 08 '17 at 09:20

1 Answers1

8

The script are always run in the default windows shell, not cygwin.

If you want it to run in bash then put this in package.json:

"scripts": {
    "test": "bash test.sh"
},

and put this in test.sh:

#!/bin/bash
mkdir mydir/mysubdir

Or, as csvan pointed out in the comment, you can use Node scripts instead of shell scripts:

"scripts": {
    "test": "node test.js"
},

This approach is even better for cross-platform compatibility.

See also:

rsp
  • 107,747
  • 29
  • 201
  • 177
  • I ended up taking this approach, but using JS scripts instead to ensure cross-platform compatibility, e.g. `"test": "node test.js"`. Accepting your answer since the overall approach is correct. – csvan Feb 08 '17 at 08:35
  • @csvan I posted a solution to run exact command from your question but yes, using JS scripts is even better for cross-platform compatibility. I'll add it to the answer. – rsp Feb 08 '17 at 08:38
  • 3
    `The script are always run in the default windows shell, not cygwin` -- this needs like about hundred more up votes... – Igor Soloydenko Jun 13 '18 at 03:20
  • @IgorSoloydenko Thanks, I'll highlight this part of the answer. – rsp Jun 14 '18 at 07:33
  • @rsp `The script are always run in the default windows shell, not cygwin` — I guess it's not always so... [script-shell](https://docs.npmjs.com/misc/config#script-shell) npm setting can override it, like that: `npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"` thus enabling bash commands in package.json scripts on Windows – Vasiliy May 06 '20 at 15:35