node.js - Behavior difference between `exec` and `spawn` -
i'm attempting create child process running mongo shell command-line arguments clone database. code functions correctly using child_process.exec(...), not child_process.spawn(...). improved security, i'd prefer use the latter.
i'm on macos 10.11.6, using mongo shell version 3.2.6 installed via brew.
uname -a
darwin blackknight 15.6.0 darwin kernel version 15.6.0: mon aug 29 20:21:34 pdt 2016; root:xnu-3248.60.11~1/release_x86_64 x86_64
mongo --version
mongodb shell version: 3.2.6
ls -la
which mongolrwxr-xr-x 1 daldridge wheel 33 jul 29 09:32 /usr/local/bin/mongo -> ../cellar/mongodb/3.2.6/bin/mongo
here's sample source:
const async = require('async'); const exec = require('child_process').exec; const spawn = require('child_process').spawn; function _getcreateargs(name) { return [ '--verbose', 'localhost:27017/admin', `--eval="db.getsiblingdb('${name}').createcollection('${name}');"`, ]; } function _getcloneargs(source, target) { return [ '--verbose', 'localhost:27017/admin', `--eval="db.copydatabase('${source}', '${target}');"`, ]; } function _childhandler(child, callback) { child.stderr.on('data', (data) => { console.log(data.tostring()); }); child.stdout.on('data', (data) => { console.log(data.tostring()); }); child.on('exit', (exitcode) => { callback(exitcode ? new error(`mongo database clone - unexpected exit code: ${exitcode}`) : null, null); }); } function _createdatabase(database, callback) { const child = exec(`mongo ${_getcreateargs(database).join(' ')}`); _childhandler(child, callback); } function _cloneviaexec(source, target, callback) { const child = exec(`mongo ${_getcloneargs(source, target).join(' ')}`); _childhandler(child, callback); } function _cloneviaspawn(source, target, callback) { const child = spawn('mongo', _getcloneargs(source, target)); _childhandler(child, callback); } const databasename = `${date.now()}`; async.waterfall([ (waterfallcallback) => { _createdatabase(databasename, waterfallcallback); }, (waterfallcallback) => { async.series(async.reflectall([ // 1 works (seriescallback) => { _cloneviaexec(databasename, 'cloneviaexec', seriescallback); }, // 1 doesn't (seriescallback) => { _cloneviaspawn(databasename, 'cloneviaspawn', seriescallback); }, ]), waterfallcallback); }, ], (error) => { if (error) { console.log(error); } }); the database , collection creations succeed (using exec), first copy attempt (also using exec), equivalent clone via spawn not work. there nothing on stderr child.
ideas?
Comments
Post a Comment