I haven't seen a solution here that is actually synchronous except for @Patrick Narkinsky's. But @Patrick Narkinsky's answer doesn't work on Windows. Seems to be a node.js bug. If you want to learn the details, feel free to go down this rabbit hole of github issues, but I gave up after an hour of reading.
- https://github.com/aws/aws-cdk/issues/11314 The issue reported here
- https://github.com/nodejs/node/issues/35997 A contributor from that library creates a node issue
- https://github.com/libuv/libuv/pull/3053 A nodejs contributor submits a PR with a fix(?) (not yet merged)
I wasn't able to find a workaround there (I probably glossed over it), but I accidentally stumbled on a solution to the problem. It's not pretty, but it works. Since that link only shows how to log the progress, I had to modify it for my own needs:
import fs from 'fs';
const BUFSIZE = 256;
const buf = Buffer.alloc(BUFSIZE);
let bytesRead;
let stdin = '';
export function stdinToString(): string {
do {
// Loop as long as stdin input is available.
bytesRead = 0;
try {
bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);
} catch (e) {
if (e.code === 'EAGAIN') {
// 'resource temporarily unavailable'
// Happens on OS X 10.8.3 (not Windows 7!), if there's no
// stdin input - typically when invoking a script without any
// input (for interactive stdin input).
// If you were to just continue, you'd create a tight loop.
throw 'ERROR: interactive stdin input not supported.';
} else if (e.code === 'EOF') {
// Happens on Windows 7, but not OS X 10.8.3:
// simply signals the end of *piped* stdin input.
break;
}
throw e; // unexpected exception
}
if (bytesRead === 0) {
// No more stdin input available.
// OS X 10.8.3: regardless of input method, this is how the end
// of input is signaled.
// Windows 7: this is how the end of input is signaled for
// *interactive* stdin input.
break;
}
// Process the chunk read.
stdin += buf.toString(undefined, 0, bytesRead);
} while (bytesRead > 0);
return stdin;
}
I've been programming for over a decade and this is the first time a do while
made my code cleaner :) Without it, this function would hang if no stdin data exists -- one could argue that was a bug in the code of that link.
This answers the original question AND works on all operating systems.