Nodejs 关于child_process中的exec和spawn

Nodejs 关于child_process中的exec和spawn

开始学习child_process模块的时候以为spawn可以直接运行命令, 后来发现这是一个小陷阱就拿出来和大家分享一下.

先说下我碰到的情况由于在windos下写的所以根据docs上的例子我就写出了这么一句代码:"require(“child_process”).spawn(“dir”), 这么写是会有错误的,用error接受到的数据是没有此文件. 而用exec就不会有问题,于是得到了以前的猜想.

大家都知道在linux下, ls命令对应的是一个文件, 而在windows下是做为cmd的内置命令的. 所以像我那样写是会报错.

于是我查看了child_process的源码发现spawn是这样定义的var spawn = exports.spawn = function(file, args, options); 也就是说他传入的应该是一个文件, 例如ping, cmd等. 而exec的源码中有一段这样的代码:

if (process.platform === ‘win32’) { file = ‘cmd.exe’; args = [’/s’, ‘/c’, ‘"’ + command + ‘"’]; // Make a shallow copy before patching so we don’t clobber the user’s // options object. options = util._extend({}, options); options.windowsVerbatimArguments = true; } else { file = ‘/bin/sh’; args = [’-c’, command]; }

所以想使用内置命令可以直接使用exec或者把spawn改成spawn(“cmd.exe”,["\s", “\c”, “dir”]);

总结起来就是spawn是调用一个文件! 不要被docs上的child_process.spawn(command, [args], [options])中的command给骗了


4 回复

Node.js 关于 child_process 中的 execspawn

开始学习 child_process 模块时,可能会遇到一些陷阱。本文将通过示例代码解释 spawnexec 的区别,并说明如何正确使用它们。

示例代码

首先,我们来看两个示例代码,分别使用 spawnexec 来执行命令。

使用 spawn

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

// 错误的用法
try {
    const dirProcess = spawn('dir'); // 在 Windows 上会报错
    dirProcess.stdout.on('data', data => console.log(data.toString()));
} catch (error) {
    console.error(error);
}

// 正确的用法
try {
    const cmdProcess = spawn('cmd.exe', ['/c', 'dir']); // 在 Windows 上正确执行
    cmdProcess.stdout.on('data', data => console.log(data.toString()));
} catch (error) {
    console.error(error);
}

使用 exec

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

// 正确的用法
exec('dir', (error, stdout, stderr) => {
    if (error) {
        console.error(`执行出错: ${stderr}`);
        return;
    }
    console.log(`stdout: ${stdout}`);
});

解释

  1. spawn

    • spawn 方法用于创建一个新的进程并执行指定的命令。
    • spawn 需要传递一个可执行文件名(如 cmd.exe)以及参数列表。
    • 在 Windows 上,dir 是一个内置命令而不是一个可执行文件,因此直接使用 spawn('dir') 会报错。
    • 正确的做法是使用 spawn('cmd.exe', ['/c', 'dir']),其中 /c 表示执行完命令后关闭命令提示符窗口。
  2. exec

    • exec 方法用于执行一个命令并将输出捕获到回调函数中。
    • exec 会自动处理不同平台上的差异,因此在 Windows 和 Linux 上都可以正确执行内置命令。
    • exec 的参数是一个完整的命令字符串,如 'dir''ls'

总结

  • 使用 spawn 时,需要传递一个可执行文件名和参数列表。
  • 使用 exec 时,可以传递一个完整的命令字符串,它会自动处理平台差异。
  • 如果你需要执行内置命令或复杂的命令链,推荐使用 exec

希望这些示例代码和解释能帮助你更好地理解和使用 child_process 模块中的 spawnexec 方法。


刚刚就被这个东西搞得半死不活的,谢谢分享!

这个 执行dir以后有乱码怎么解决啊

spawnexec 是 Node.js 中用于执行子进程的方法,但它们有不同的使用场景和方式。

spawn

spawn 方法更高效,因为它不会缓冲整个输出。它返回一个可读的流(stdout 和 stderr),可以实时处理输出。spawn 需要指定要执行的程序及其参数。

示例代码:

const { spawn } = require('child_process');
const dir = spawn('dir', [], { shell: true });

dir.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

dir.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

dir.on('close', (code) => {
  console.log(`子进程退出,退出码 ${code}`);
});

exec

exec 会缓冲所有输出,并在子进程退出后返回输出结果。适用于输出较小的场景,因为它需要等待子进程结束才能获取输出。

示例代码:

const { exec } = require('child_process');
exec('dir', (error, stdout, stderr) => {
  if (error) {
    console.error(`执行出错: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
});

总结

  • 使用 spawn 时,要确保传递的参数是一个可执行文件或命令,而不是直接传递一个命令字符串。
  • 在 Windows 下,如果需要执行类似 dir 这样的命令,应使用 spawn('cmd.exe', ['/c', 'dir']) 或者直接使用 exec

这样可以避免因路径或环境问题导致的错误。

回到顶部