Created
October 27, 2017 09:32
-
-
Save papandreou/47f5b043a5cff4025937787988a04680 to your computer and use it in GitHub Desktop.
Helper for running a shell command and buffering up its output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const childProcess = require('child_process'); | |
function consumeStream(stream) { | |
return new Promise((resolve, reject) => { | |
const buffers = []; | |
stream | |
.on('data', buffer => buffers.push(buffer)) | |
.on('end', () => resolve(Buffer.concat(buffers))) | |
.on('error', reject); | |
}); | |
} | |
async function run(commandAndArgs, stdin) { | |
if (typeof commandAndArgs !== 'undefined' && !Array.isArray(commandAndArgs)) { | |
commandAndArgs = [ commandAndArgs ]; | |
} | |
const proc = childProcess.spawn(commandAndArgs[0], commandAndArgs.slice(1)); | |
const promises = { | |
exit: new Promise((resolve, reject) => { | |
proc | |
.on('error', reject) | |
.on('exit', exitCode => { | |
if (exitCode === 0) { | |
resolve(); | |
} else { | |
reject(new Error(`Child process exited with ${exitCode}`)); | |
} | |
}); | |
}), | |
stdin: new Promise((resolve, reject) => { | |
proc.stdin | |
.on('error', reject) | |
.on('close', resolve); | |
}), | |
stdout: consumeStream(proc.stdout), | |
stderr: consumeStream(proc.stderr) | |
}; | |
if (typeof stdin === 'undefined') { | |
proc.stdin.end(); | |
} else { | |
proc.stdin.end(stdin); | |
} | |
try { | |
await Promise.all(Object.values(promises)); | |
return [ | |
await promises.stdout, | |
await promises.stderr | |
]; | |
} catch (err) { | |
err.stdout = await promises.stdout; | |
err.stderr = await promises.stderr; | |
throw err; | |
} | |
} | |
// Use it :) | |
(async () => { | |
try { | |
const [ stdout, stderr ] = await run(['python', 'foo', 'bar'], 'stuff for stdin'); | |
console.log(`yay, success, stdout ${stdout}`); | |
} catch (e) { | |
console.log(`oh dear, command exited with ${e.code} and stderr ${e.stderr} and stdout ${e.stdout}`); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment