一个脚手架里有两个命令,我在主命令里使用execa调用另外一个子命令,子命令通过终端交互后会返回数据,我怎么在主命令中获取到这个数据,使用方法如下
const {stdout} =await execa("node", ["bin/main.js", "el"], {
stdio: "inherit",
});
我尝试使用stdio:pipe,但是我的子命令需要终端交互才能获得数据
一个脚手架里有两个命令,我在主命令里使用execa调用另外一个子命令,子命令通过终端交互后会返回数据,我怎么在主命令中获取到这个数据,使用方法如下
const {stdout} =await execa("node", ["bin/main.js", "el"], {
stdio: "inherit",
});
我尝试使用stdio:pipe,但是我的子命令需要终端交互才能获得数据
在使用 execa
库与子进程进行通信时,如果你需要捕获子进程的输出并且子进程依赖于终端交互(如等待用户输入),你需要正确地设置 stdio
选项。在你的情况下,使用 stdio: "inherit"
会使得子进程的输入输出直接继承自父进程(即终端),这通常用于调试或当你希望子进程的输出直接显示在终端上。然而,这样做无法捕获子进程的输出到变量中。
要捕获子进程的输出并且允许终端交互,你可以使用 stdio: ['pipe', 'inherit', 'inherit']
。这里的数组分别代表 stdin
、stdout
和 stderr
的处理方式:
stdin: 'pipe'
允许你从父进程向子进程发送数据(虽然在你的例子中可能不需要)。stdout: 'inherit'
使得子进程的输出显示在终端上(这对于交互是必需的)。stderr: 'inherit'
使得错误输出也显示在终端上(可选,但通常很有用)。然而,由于你希望捕获输出,你可以将 stdout
设置为 'pipe'
而不是 'inherit'
。但这样做会阻止子进程直接接收来自终端的输入(如用户交互)。为了解决这个问题,你可能需要模拟或转发用户的输入到子进程。
解决方案:
如果子命令不需要用户交互:
stdio
设置为 ['ignore', 'pipe', 'pipe']
(忽略输入,捕获输出和错误)。如果子命令需要用户交互:
示例代码(不需要用户交互):
const { execa } = require('execa');
(async () => {
try {
const { stdout, stderr } = await execa("node", ["bin/main.js", "el"], {
stdio: ['ignore', 'pipe', 'pipe']
});
console.log('stdout:', stdout);
if (stderr) {
console.error('stderr:', stderr);
}
} catch (error) {
console.error('Error:', error);
}
})();
注意,这种方法不会显示任何子进程的输出到终端,除非你手动打印它。如果你确实需要显示输出并捕获它,你可能需要更复杂的逻辑来处理输入输出流,这通常涉及到使用 Node.js 的流(streams)功能来监听和转发数据。
2 回答4.1k 阅读✓ 已解决
3 回答7.9k 阅读
1 回答4.5k 阅读✓ 已解决
2 回答5.6k 阅读
2 回答1.7k 阅读✓ 已解决
4 回答806 阅读✓ 已解决
4 回答1.1k 阅读✓ 已解决