5

I have a very simple shell script, test.sh

#!/usr/bin/env bash

exit 1

I'm calling this from my test run script in package.json

"scripts": {
  "test": "test.sh && echo \"unexpected output\""
},

Running npm test I get this:

$ npm test

> testtest@1.0.0 test C:\Users\[path]\testtest
> test.sh && echo "unexpected output"

"unexpected output"

It seems as if npm doesn't care about the non-zero exit code of test.sh. I was not expecting to see "unexpected output".

How do I make the execution of the "test" command stop when one of the steps it performs (test.sh in this case) exits with an error?

With this in my package.json: "test": "test.sh && echo $?",
This is the output:

$ npm test

> testtest@1.0.0 test C:\Users\[path]\testtest
> test.sh && echo $?

$?

With this: "test": "test.sh && echo \"$?\"",
I get this:

$ npm test

> testtest@1.0.0 test C:\Users\[path]\testtest
> test.sh && echo "$?"

"$?"

As a sanity-check I added an echo after the exit in test.sh. Thankfully it doesn't print :)

#!/usr/bin/env bash

exit 1

echo "This should not print"

The "This should not print" text never shows up in my console.

Actually, adding an echo before exit 1 also doesn't print anything to my GitBash console. Instead it prints to a temporary cmd window that npm launches. So I'm guessing the exit status is lost inside that cmd session.

Tobbe
  • 3,282
  • 6
  • 41
  • 53
  • Can you post what happens when you replace the echo message with `echo $?` (just to make sure the exit code is correctly arriving as 1). [$? returns the exit code of the last run command](http://bencane.com/2014/09/02/understanding-exit-codes-and-how-to-use-them-in-bash-scripts/). – Squirrel Jan 22 '18 at 18:40
  • @Squirrel I get the literal string `$?` :( – Tobbe Jan 22 '18 at 19:56
  • One idea would be to try set -e ([as explained in this question](https://stackoverflow.com/questions/3474526/stop-on-first-error)), maybe the .sh script is not being stopped correctly by node? Also, just to make sure, your line ended up as `test.sh && echo $?`, right? – Squirrel Jan 22 '18 at 20:00
  • @Squirrel I updated the question with info about what I ran and the output. I also just now tried with `set -e` in test.sh. Didn't make any difference – Tobbe Jan 22 '18 at 20:04
  • Can you check that, if adding some `echo`s under the `exit 1` command in the .sh file, they are actually not displayed? – Squirrel Jan 22 '18 at 20:35
  • Yeah, it doesn't print anything – Tobbe Jan 22 '18 at 21:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163709/discussion-between-squirrel-and-tobbe). – Squirrel Jan 23 '18 at 12:06
  • 1
    @Squirrel Just found this page, encountering the same problem, and very disappointed to find that the solution was kept to a private chat :( – Katie Aug 07 '19 at 20:28
  • 1
    @Katie No solution was ever found :( – Tobbe Aug 08 '19 at 21:05

1 Answers1

3

This worked for me:

"scripts": {
  "test": "bash test.sh && echo \"unexpected output\""
},

With the additional "bash", the script runs in the current Git Bash. The "unexpected output" is not printed. If I omit the "bash", a new Bash window is opened, and I also get the "unexpected output".

$ npm test

> npm2@1.0.0 test D:\Martin\dev\npm-test\npm2
> bash test.sh && echo "unexpected output"

Hi from script! Next: exit 1
npm ERR! Test failed.  See above for more details.

As a side note, if you're developing a cross-platform Node.js project, it might be better to avoid Bash/Cmd/Powershell scripts. Just use Node.js scripts instead, and you don't need additional tools to be installed.

mh8020
  • 1,784
  • 1
  • 11
  • 14
  • "Just use Node.js scripts instead, and you don't need additional tools to be installed." -- I have the same problem with .js files that call `process.exit()`. How did you get it to work? – Bbrk24 Oct 22 '21 at 01:32
  • 1
    @Bbrk24 I do not have this problem (Win10, Node 12): `"scripts": { "test0": "node index.js 0 && echo \"Expected output\"", "test1": "node index.js 1 && echo \"Unexpected output\"" },`. Index.js contains: `var code = parseInt(process.argv[2]); console.log('exit ' + code); process.exit(code);`. When I run `npm run test0`, I get "exit 0 / Expected output". When I run `npm run test1`, I only get "exit 1", as expected. – mh8020 Oct 26 '21 at 20:42