如何得知child_process退出
发布于 11 年前 作者 supersheep 5889 次浏览 最后一次编辑是 8 年前

就是如果我希望通过自己的程序去调用npm init这样的进程 这就需要把自己和子进程之间的输入输出做一下pipe

process.stdin.pipe(child.stdin);
child.stdout.pipe(process.stdout);

其他方面都没问题,但是我如何知道npm init退出了呢? 目前的情况是进行到 Is this ok? (yes), 我敲回车之后,没有任何的事件被检测到了

我自己写了个简单的例子,用同样的方法去操作

var prompt = require('prompt');
prompt.start();
prompt.get(['username', 'email'], function (err, result) {
  console.log('Command-line input received:');
  console.log(' username: ' + result.username);
  console.log(' email: ' + result.email);
  process.exit(0);
});

这里,如果不执行process.exit(0),就会像刚才一样无法探测到。 而有了这句的话,我就可以

child.stdout.on('end', function() {});

或者

child.on('exit',function(){});

来得知

从而在袭击的程序中调用process.exit()退出。

是不是有什么机制我不知道的?或者,node本身在没有process.exit(0)的时候如何知道在什么时候退出运行?

1 回复

发现可以通过设置stdio选项为inherit来实现,顺带翻译了一下文档

child_process.spawn() 中的 stdio 选项是一个数组,每个索引对应子进程中的一个文件标识符。可以是下列值之一:

  1. 'pipe' -在子进程与父进程之间创建一个管道,管道的父进程端以 child_process 的属性的形式暴露给父进程,如 ChildProcess.stdio[fd]。 为 文件标识(fds) 0 - 2 建立的管道也可以通过 ChildProcess.stdin,ChildProcess.stdout 及 ChildProcess.stderr 分别访问。

  2. 'ipc' - 创建一个IPC通道以在父进程与子进程之间传递 消息/文件标识符。一个子进程只能有最多一个 IPC stdio 文件标识。 设置该选项激活 ChildProcess.send() 方法。如果子进程向此文件标识符写JSON消息,则会触发 ChildProcess.on(“message”)。 如果子进程是一个nodejs程序,那么IPC通道的存在会激活process.send()和process.on(‘message’)

  3. 'ignore' - 不在子进程中设置该文件标识。注意,Node 总是会为其spawn的进程打开 文件标识(fd) 0 - 2。 当其中任意一项被 ignored,node 会打开 /dev/null 并将其附给子进程的文件标识(fd)。

  4. Stream 对象 - 与子进程共享一个与tty,文件,socket,或者管道(pipe)相关的可读或可写流。 该流底层(underlying)的文件标识在子进程中被复制给stdio数组索引对应的文件标识(fd)

  5. 正数 - 该整形值被解释为父进程中打开的文件标识符。他与子进程共享,和Stream被共享的方式相似。

  6. null, undefined - 使用默认值。 对于stdio fds 0,1,2(或者说stdin,stdout和stderr),pipe管道被建立。对于fd 3及往后,默认为ignore

按照文档的意思,默认情况下,stdio的值为 [‘pipe’,‘pipe’,‘pipe’],作用就是让父进程可以拿到子进程的stdin,stdout,stderr,但具体作何操作,看具体需求。

如果是ignore,就拿不到这几对象。

而如果传Stream,则会在把子进程中的流复制给父进程达到同步的效果 (The stream’s underlying file descriptor is duplicated in the child process to the fd that corresponds to the index in the stdio array.)

不过我还是不太理解单纯的pipe与用stdio传递Stream当中有什么细微的差别。

回到顶部