I'm working on spawn
on nodejs. previously I was using exec
but exec has no compatibility in stdout (or stderr) steaming.
now, I have a disability about spawn. It seems whereas exec accepted quoted string command, spawn does not accepted that one, just array format.
so following exec script is working correctly but another one which uses spawn will be error, due to string formatted command not array.
const exec = require('child_process').exec;
exec(` echo foo bar `, (error, stdout, stderr) => {
if ( error ){ console.log(error) }
if ( stdout ){ console.log(stdout) }
if ( stderr ){ console.log(stderr) }
});
const { spawn } = require('child_process');
command = spawn('echo foo bar');
command.stdout.on('data', function (data) {
console.log(data.toString());
});
command.stderr.on('data', function (data) {
console.log( data.toString());
});
command.on('exit', function (code) {
console.log( code.toString());
});
I have a lot of command line script which is what I want to spawn
on nodejs, and all of them are complicated, something like following one. that's why I want to use string format for specify command rather than array. Any idea?
exec(' bash -ic "expecto \\"sudo bash -ic \\\\\\"rd ; backup_important_batch\\\\\\"\\" $PASSWORD" ', (error, stdout, stderr) => {
if ( error ){ console.log(error) }
if ( stdout ){ console.log(stdout) }
if ( stderr ){ console.log(stderr) }
});
The spawn function launches a command in a new process and we can use it to pass that command any arguments. For example, here's code to spawn a new process that will execute the pwd command. const { spawn } = require('child_process'); const child = spawn('pwd');
child_process.exec() : spawns a shell and runs a command within that shell, passing the stdout and stderr to a callback function when complete.
The de facto standard input/output manager for Node.js. After a very long time, finally version 2 is here. The cool stdio module you cannot live without has been rewritten and improved a lot, with Typescript support, promise-based usage and much more. Note: Version 2 stops supporting non promise-based usage.
You can't split on spaces because many command line args may include strings like ./foo.js --bar "Hello Baz"
, splitting on the string will incorrectly give you "Hello
Baz"
as arguments.
Use a library like https://www.npmjs.com/package/string-argv to convert the string into arguments that you can pass the string to, get an array result and build your spawn()
call.
Edit: Here's an example:
const { spawn } = require('child_process');
const { parseArgsStringToArgv } = require('string-argv');
async function run(command) {
return new Promise( resolve => {
let args = parseArgsStringToArgv(command);
let cmd = args.shift();
console.log(cmd, args);
let step = spawn(cmd, args);
step.stdout.pipe(process.stdout);
step.stderr.pipe(process.stderr);
step.on('close', (code) => {
resolve(code);
});
});
}
let name = 'Baz';
let exitCode = await run(`echo "Hello ${name}"`);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With