带有字符串而不是数组的nodejs spawn命令?

k23*_*3j4 6 node.js

我正在研究spawnnodejs。以前我使用过,exec但 exec 在 stdout(或 stderr)流中没有兼容性。现在,我对 spawn 有障碍。似乎 exec 接受了带引号的字符串命令,而 spawn 不接受那个命令,只是数组格式。

所以下面的 exec 脚本工作正常,但另一个使用 spawn 的脚本会出错,因为字符串格式的命令不是数组。

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) }
});
Run Code Online (Sandbox Code Playgroud)
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());
});

Run Code Online (Sandbox Code Playgroud)

我有很多命令行脚本,这是我想要spawn在 nodejs 上使用的,而且它们都很复杂,就像下面一个。这就是为什么我想使用字符串格式来指定命令而不是数组。任何的想法?

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) }
});
Run Code Online (Sandbox Code Playgroud)

Jay*_*ulx 7

您不能在空格上拆分,因为许多命令行参数可能包含诸如 之类./foo.js --bar "Hello Baz"的字符串,在字符串上拆分会错误地将您"Hello Baz"作为参数提供。

使用诸如https://www.npmjs.com/package/string-argv 之类的库将字符串转换为您可以将字符串传递给的参数,获取数组结果并构建您的spawn()调用。

编辑:这是一个例子:

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}"`);
Run Code Online (Sandbox Code Playgroud)


小智 1

尝试自动拆分命令,例如:

const { spawn } = require('child_process');

let cmd = 'echo foo bar'
let cmdarray = cmd.split(" ");
let command = spawn(cmdarray.shift(), cmdarray);
Run Code Online (Sandbox Code Playgroud)