Skip to content

Latest commit

 

History

History
141 lines (101 loc) · 4.11 KB

2.3.6 node spawn-cross-spawn.md

File metadata and controls

141 lines (101 loc) · 4.11 KB

2.3.6 node spawn

本质上使用 child_process.spawnSync(), child_process.spawn();

源码

function spawn(command, args, options) {
    // Parse the arguments
    const parsed = parse(command, args, options);

    // Spawn the child process
    const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);

    // Hook into child process "exit" event to emit an error if the command
    // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
    enoent.hookChildProcess(spawned, parsed);

    return spawned;
}

function spawnSync(command, args, options) {
    // Parse the arguments
    const parsed = parse(command, args, options);

    // Spawn the child process
    const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);

    // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
    result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);

    return result;
}
var mkdir = 'mkdir -p ./downloads/';
var child = exec(mkdir, function(err, stdout, stderr) {
  if (err) throw err;
  else download_file_httpget(file_url);
});

windows中使用 exec 执行命令出现 Command failed: mkdir -p ./downloads/, mkdir 这个不支持 windows

可以使用node-mkdirp

spawn 和 exec

spawn :创建子进程 nodejs中spawn和exec的区别: 都可以在命令行执行命令

  • spawn
    • 返回值: stream
    • 方式异步输出stdout stderr
    • 适合:适合处理large data 、 img 、 binary
  • exec
    • 返回值: buffer
    • 方式:异步
    • 默认缓冲区大小200k

三种不同方式处理文件下载,http, spawn + curl ,exec +wget

Node.js 的子进程 (child_process) 模块下有一 spawn 函数,可以用于调用系统上的命令

在 Linux, macOS 等系统上,我们可以执行

const spawn = require('child_process').spawn;

spawn('npm', {
 stdio: 'inherit'
});
来调用 npm 命令。

然而,同样的语句在 Windows 上执行则会报错。

因为在 Windows 上,当我们执行 npm 时,我们实际执行的是 npm.cmd 批处理,而在 Windows 上,
.cmd,  .bat 批处理是无法脱离 cmd.exe 这一解释器而单独运行的。

因此,我们需要显式地调用 cmd:
spawn('cmd', ['/c', 'npm'], {
 stdio: 'inherit'
});

或者使用在调用 spawn 函数时,设置 shell 选项为 true 以隐式地调用 cmd (该选项添加自 Node.js v6 版本)
spawn('npm', {
 stdio: 'inherit',
 shell: true
});

另外,虽然在 Linux, macOS 等系统上不需要设置 shell 选项,命令也能够正常执行;
设置 shell 为 true 也不会妨碍命令的执行,只是会额外的产生一个本不必要的 shell 进程,影响性能。

因此,如果想要编写跨平台的 spawn 命令,而又不想增加额外的开销的话,可以这样写

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

spawn('npm', {
 stdio: 'inherit',
 // 仅在当前运行环境为 Windows 时,才使用 shell
 shell: process.platform === 'win32'
});

cross-spawn

关于 spawn 函数的跨平台写法,除了自己编写代码的时候做处理,也有第三方模块封装好了相关细节,如 cross-spawn

npm install cross-spawn

用法

const spawn = require('cross-spawn');

spawn('npm', {
 stdio: 'inherit'
});

使用git clone

const res = spawn.sync('git', ['clone', '--depth=1', `https://github.com/wechat-miniprogram/kbone-template-vue`, 'demo' || '.'], {
 stdio: 'inherit',
 // shell: true // 仅在当前运行环境为 Windows 时,才使用 shell
 shell: process.platform === 'win32'
});

windows 环境需要使用 shell  { stdio: 'inherit', shell: process.platform === 'win32' }

参考