这段代码定义了一个 execQuick 函数,它使用 spawn 子进程的方式执行一条命令。spawn 子进程的优点是比 exec 更高效,因为它不需要创建新的 shell 环境,并且不会因超出最大缓冲区的限制而导致错误。
execQuick 函数接受一条命令和一些选项作为参数,并返回一个包含命令执行结果的 Promise 对象。
1.如果用户指定了 time 选项,execQuick 会在执行完命令后打印出命令执行所花费的时间;
2.如果用户指定了 silent 选项,execQuick 会禁止打印出命令的标准输出和标准错误输出。
import { spawn } from 'child_process';
import print from './print';
/**
* spawn优于exec的点
* 1是在于不用新建shell,减少性能开销
* 2是没有maxbuffer的限制
*/
export default async function execQuick(
command: string,
options: {
cwd?: string;
time?: boolean;
silent?: boolean;
} = {}
): Promise<{ pid: number; code: number; stdout: string; stderr: string }> {
return new Promise((resolve) => {
const silent = options.silent !== false;
const begin = new Date().getTime();
const result = {
pid: null,
code: null,
stdout: '',
stderr: '',
};
const { stdout, stderr, pid } = spawn(command, {
cwd: options.cwd,
shell: true,
}).on('close', (code) => {
if (options.time) {
const end = new Date().getTime();
const waste = ((end - begin) / 1000).toFixed(2);
print.info(command, `Command executed in ${waste} ms.`);
}
if (code !== 0 && !silent) {
print.error(command, 'Command executed failed');
}
result.code = code;
resolve(result);
});
result.pid = pid;
stdout.on('data', (data) => {
const dataStr = data.toString();
if (!silent) {
print.info(dataStr);
}
result.stdout += dataStr;
});
stderr.on('data', (data) => {
const dataStr = data.toString();
if (!silent) {
print.error(dataStr);
}
result.stderr += dataStr;
});
});
}