Skip to content

fix(cli): exit when the command dies from SIGPIPE - #1078

Merged
motdotla merged 1 commit into
motdotla:masterfrom
NgoQuocViet2001:fix-cli-ignored-signal-hang
Oct 29, 2026
Merged

motdotla merged 1 commit into
motdotla:masterfrom
NgoQuocViet2001:fix-cli-ignored-signal-hang

Conversation

@NgoQuocViet2001

Copy link
Copy Markdown
Contributor

When the command started by dotenv run is killed by SIGPIPE, the CLI never exits. Native tools get SIGPIPE when the reader of a pipe stops early, for example dotenv run -- cat app.log | head or dotenv run -- grep ERROR app.log | head on a large file. The output is printed, then the pipeline hangs until Ctrl-C or a CI timeout. The same command without dotenv exits with 141.

The exit handler re-raises the child's signal on itself and keeps the event loop alive with a setInterval until that signal arrives. Node ignores SIGPIPE, so it never arrives and the process stays alive forever. This replaces the interval with a 1s setTimeout that exits with the shell's 128 + signal number status. Signals Node does not ignore still terminate the process by signal as before. SIGXFSZ had the same hang and now exits 153.

Ran:

  • npm test on Windows: 1412 pass, 1 skip (POSIX signal tests skip on win32)
  • full tap suite on Linux: 1418 pass, 1 skip
  • new test in tests/test-cli-signals.js: fails on master with ETIMEDOUT, passes with the fix

Checked:

  • cat/grep on a 1M-line file piped to head -n 1: PIPESTATUS 124 0 (timeout) on master, 141 0 with the fix
  • sh -c 'kill -TERM $$' still exits 143, sh -c 'kill -KILL $$' 137, sh -c 'exit 7' 7

@motdotla

Copy link
Copy Markdown
Owner

nice catch

@motdotla
motdotla merged commit 32ab610 into motdotla:master Oct 29, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants