open-cli-tools / open-cli-tools/concurrently
concurrently exitcode=0 when it receives SIGINT itself (e.g. on ^C)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.9k
- Forks
- 281
- Avg merge
- 17h 12m
- Merged PRs (30d)
- 1
Description
MacOS and Linux at least.
Sounds like concurrently tool reaction on receiving SIGINT is exiting with code 0 (instead of exiting with e.g. code 130 as the best-practice reaction on Unix processes). This breaks scripts like:
#!/bin/bash
set -e # stop on failed commands
concurrently "one" "two"
echo "still here"
When ^C is pressed in the above script, it still prints "still there", although it should not.
The reason why proper SIGINT handling is important is also described here: https://mywiki.wooledge.org/SignalTrap#When_is_the_signal_handled.3F, section "Special Note On SIGINT and SIGQUIT".
Repro
Console 1:
$ node_modules/.bin/concurrently --version
8.2.2
$ bash -c "node_modules/.bin/concurrently 'exec sleep 1000' 'exec sleep 2000' && echo Exited with exitcode=0"
Console 2:
$ watch -n0.5 'pstree | egrep "sleep" | egrep -v egrep'
Then ^C in console 3:
When ^C is pressed, SIGINT is sent to the entire process group (which is -78069 in this example). I.e. SIGINT is sent to all 4 processes on the screenshot. The bug is that, when concurrently itself receives that SIGINT, it exits with exitcode=0, i.e. it tells the caller that it terminated successfully, although it's not true. According to default unix practices, the process killed by SIGINT should exit with a nonzero exit code (ideally with code=130 which is 128+SIGINT).
We can reproduce the same behavior by not pressing ^C, but by:
- Sending SIGINT to
concurrentlypid itself. - OR - by sending SIGINT to the whole process group, like
kill -SIGINT -78069in the above example.
Interestingly enough, this happens only when receiving SIGINT. On e.g. SIGTERM or SIGHUP it behaves properly.
P.S.
There is an ugly work-around for this:
bash -c 'node_modules/.bin/concurrently "exec sleep 1000" "exec sleep 2000" & wait $! && echo Exited with exitcode=0'
Since the shell itself also receives that ^C SIGINT (it's a member of the process group), it fails in wait call, so the message is not printed. But again, this is not a good practice (it is based on a side effect, e.g. it still doesn't help when there is no ^C involved, and only concurrently tool is sent with a SIGINT).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the concurrently CLI entry point invoked through node_modules/.bin/concurrently, then reproduce the SIGINT cases in the issue using the provided bash commands. Done means SIGINT causes concurrently to return a nonzero status, ideally 130, so the surrounding script does not print its success message.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100