我正在节点中构建一个命令行工具,作为该工具的一部分,我需要执行系统中的命令。 问题是我没有从程序中生成的子进程获得管道输出
执行子进程的代码:
import * as Child_process from "child_process";
export function asyncExec(command: string): Promise<string> {
return new Promise((resolve, reject) => {
const child = Child_process.spawn(command, { shell: true });
child.stdout?.pipe(process.stdout);
child.on("error", (err) => {
reject(err);
});
child.on("exit", (code) => {
if (code === 0) {
resolve(code.toString());
} else {
reject(new Error(`Process exited with code ${code}`));
}
});
});
}
我有此代码的另一个版本来尝试使用 exec 使其工作
import * as Child_process from "child_process";
export function asyncExec(command: string): Promise<string> {
return new Promise((resolve, reject) => {
const child = Child_process.exec(command, (err, stdout, stderr) => {
if (err) {
reject(new Error(stderr || err.message));
} else {
resolve(stdout);
}
});
child.stdout?.pipe(process.stdout);
});
}
子进程的stdout流没有被打印,只有在promise解决后才打印
为什么?我能做什么来解决这个问题?
这取决于您正在执行的终端命令
process.stdout
是 readable stream
,默认情况下 highWaterMark
值为 16384
。
如果输出小于这个大小,那么一旦流结束你就会得到所有的响应,否则你会在每个数据块上得到它
尝试例如超时的大输出
await asyncExec("printf 'k%.0s' {1..100} ");
await asyncExec("printf 'k%.0s' {1..1000000000} ");
有关流 highWaterMark 的进一步阅读 这里有一个很好的解释:
问题的解决方法如下:
const child = Child_process.spawn(command, { shell: true, stdio: "inherit" });