使用命名管道作为标准输入生成节点 child_process

Posted

技术标签:

【中文标题】使用命名管道作为标准输入生成节点 child_process【英文标题】:Spawn node child_process with named pipe as stdin 【发布时间】:2013-03-25 20:59:24 【问题描述】:

假设我在 linux 上有一个命名管道:

mkfifo lk.log

从命令行,我可以打印出任何写入名称管道文件的内容。

node monitor.js < lk.log

假装这就是脚本的样子

// monitor.js

process.stdin.resume();
process.stdin.setEncoding('utf8');

// read data from stdin
process.stdin.on('data', function(chunk) 
    console.log(chunk);
);

我如何在节点中使用 child_process.spawn

child_process.spawn('node', ['monitor.js'])...

【问题讨论】:

【参考方案1】:

最简单的方法是使用exec()

var exec = require('child_process').exec;

exec('node monitor.js < lk.log', function(err, stdout, stderr) 
  ...
);

更精细的方法是在节点中打开命名管道并将其作为标准输入传递给您正在生成的进程(请参阅the option stdio for spawn)。

【讨论】:

child_process.exec 对我没有帮助,因为它会等待子进程终止,然后才能从子进程的标准输出中读取数据。 糟糕,你是对的。我想检查 spawn 的 stdio 选项是你唯一的选择。【参考方案2】:

答案是像这样使用fs.openchild_process.spawn 中的stdio 选项:

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

var fd_stdin = fs.openSync('lk.log', 'r');
spawn('node', ['monitor.js'], 
    stdio: [fd_stdin, 1, 2];
);

【讨论】:

【参考方案3】:

来自 Ben Noordhuis(核心节点贡献者) - 2011 年 10 月 11 日

Windows 有命名管道的概念,但既然你提到了mkfifo 我 假设您的意思是 UNIX FIFO。

我们不支持它们,而且可能永远不会支持(非阻塞中的 FIFO 模式有可能使事件循环死锁),但您可以使用 如果您需要类似的功能,请使用 UNIX 套接字。

https://groups.google.com/d/msg/nodejs/9TvDwCWaB5c/udQPigFvmgAJ

对于 unix 套接字,请参阅:https://***.com/a/18226566/977939

【讨论】:

以上是关于使用命名管道作为标准输入生成节点 child_process的主要内容,如果未能解决你的问题,请参考以下文章

linux命令命名管道(mkfifo)+ 结合xargs命令使用

使用命名管道向 ffmpeg 提供输入

命名管道(C#)

在进程通信中管道作为标准输入/标准输出。

如何跨(计算)节点使用 unix 管道?

检测命名管道与 I/O 完成断开连接