Node.js子进程和管道-OSX与Ubuntu

Node.js子进程和管道-OSX与Ubuntu,node.js,child-process,pipe,strace,ubuntu,Node.js,Child Process,Pipe,Strace,Ubuntu,我正在尝试使用管道和节点模块让两个长时间运行的进程进行通信——一个是父进程,一个是子进程。我希望子系统能够异步地将数据发送回父系统,并且我希望使用一个 以下是我的代码的简化版本: 起源: cp=require('child\u process') es=require(‘事件流’) child=cp.spawn('coffee',['child.coffee'],{stdio:[null,null,null,'pipe']}) so=child.stdout.pipe(es.split()) p

我正在尝试使用管道和节点模块让两个长时间运行的进程进行通信——一个是父进程,一个是子进程。我希望子系统能够异步地将数据发送回父系统,并且我希望使用一个

以下是我的代码的简化版本:

起源:
cp=require('child\u process')
es=require(‘事件流’)
child=cp.spawn('coffee',['child.coffee'],{stdio:[null,null,null,'pipe']})
so=child.stdout.pipe(es.split())
p3=child.stdio[3]。管道(es.split())
关于‘数据’,(数据)->
console.log('stdout:'+数据)
“数据”上的child.stderr.on,(数据)->
log('stderr:'+数据);
p3.关于‘数据’,(数据)->
console.log('stdio3:'+数据);
child.on“close”(代码)->
console.log('子进程以代码'+代码退出)
child.stdin.write“来自父母的消息”,“utf8”
儿童:
fs=require('fs'))
p3=fs.createWriteStream('/dev/fd/3',{encoding:'utf8'})
process.stdin.on‘数据’,(数据)->
p3.write“hello{process.pid}-{data}\n”,'utf8'
process.stdout.write“world#{process.pid}-#{data}\n”,'utf8'
p3.结束()
进程。退出(0)
process.stdin.on'end'(数据)->
console.log“标准输入结束”
p3.结束()
进程。退出(0)
process.stdin.setEncoding('utf8')
process.stdin.resume()
该代码在OSX 10.9上运行,但无法在Ubuntu设备上运行。我试过在Ubuntu 12.04和14.04下运行它。我正在运行Node 10.2x

Ubuntu下的
/dev/fd/
符号链接到
/proc/self/fd/
,因此我相信我的子进程正在打开正确的文件

在Ubuntu上运行父级的输出如下:

$ coffee parent.coffee 
stderr: 

stderr: events.js:72

stderr:         throw er; // Unhandled 'error' event

stderr:  
stderr:  
stderr:  
stderr:  
stderr:           ^

stderr: Error: UNKNOWN, open '/dev/fd/3'




events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: read ECONNRESET
  at errnoException (net.js:901:11)
  at Pipe.onread (net.js:556:19)
我希望看到(并在OSX盒上看到):

在Ubuntu上也可以使用命令行与子进程通信,因此在生成子进程时,父进程中可能存在问题:

$ echo foo | coffee child.coffee 3>&1
hello 3077 - foo

world 3077 - foo

我曾尝试研究node使用的内核调用,但对输出没有多大意义。

我自己找到了答案。错误在孩子身上。Ubuntu linux在打开已经打开的文件时更加严格,行:

p3 = fs.createWriteStream('/dev/fd/3', {encoding: 'utf8'})
他犯了一个错误。子项运行时,文件描述符
3
已打开,因此代码应如下所示:

$ coffee parent.coffee 
stderr: 

stderr: events.js:72

stderr:         throw er; // Unhandled 'error' event

stderr:  
stderr:  
stderr:  
stderr:  
stderr:           ^

stderr: Error: UNKNOWN, open '/dev/fd/3'




events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: read ECONNRESET
  at errnoException (net.js:901:11)
  at Pipe.onread (net.js:556:19)
儿童:
fs=require('fs'))
#父级在生成子级时打开文件描述符3(并在子级返回时关闭)
fd3write=(s)->
b=新缓冲区
fs.writeSync(3,b,0,b.length)
process.stdin.on‘数据’,(数据)->
fd3write“p3{process.pid}-{data}\n”
process.stdout.write“so#{process.pid}-#{data}\n”,'utf8'
进程。退出(0)
process.stdin.on'end'(数据)->
console.log“标准输入结束”
进程。退出(0)
process.stdin.setEncoding('utf8')
process.stdin.resume()
我希望这会对其他人有所帮助


要使用管道而不是stdin将消息从父级发送到子级,此链接可能有用:。

当两个进程都运行时,
ps aux | grep node
的输出是什么?@ChrisLacko命令
coffee parent。coffee
立即崩溃。在OSX上,它打印出它应该打印的内容,然后退出。我可以将运行日志时看到的错误添加到日志中。