使用sudo生成的节点不能使用ipc

时间:2017-03-08 10:11:13

标签: node.js ipc sudo spawn

在我的项目中,我需要创建一个子进程并通过IPC与它进行通信,同时,这个子进程必须以root身份运行。所以我使用cp.spawn('sudo', ...)和IPC频道,但我发现process.send方法是undefined

以下是代码:

file:parent.js

'use strict'

const cp = require('child_process')
const path = require('path')

const script = path.join(__dirname, 'child.js')

let child = cp.spawn('sudo', [process.execPath, script], {
  stdio: ['inherit', 'inherit', 'inherit', 'ipc']
})

child.on('message', msg => {
  console.log('message> ', msg)
})

console.log('parent> parent run!')

file:child.js

'use strict'

console.log('child> child run!')

process.send('hahaha')

运行node parent.js

parent> parent run!
Password:
child> child run!
/Users/zoujie.wzj/workbench/child.js:5
process.send('hahaha')
        ^

TypeError: process.send is not a function
    at Object.<anonymous> (/Users/zoujie.wzj/workbench/child.js:5:9)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

更新:将cp.spawn('sudo', ...)替换为cp.spawn(process.execPath, ...)后,该程序将正常运行:

parent> parent run!
child> child run!
message>  hahaha

有谁知道为什么IPC不能与sudo一起使用?

2 个答案:

答案 0 :(得分:0)

尝试删除所有 inherit,IPC应该有效。

请注意,您的代码不会打印“哈哈哈”。孩子发送的消息,因为您没有等待或阻止;所以当你运行parent.js时,它会执行每一行并静默(并且干净地)退出。

答案 1 :(得分:0)

如文档中所述:

  

如果子节点是Node.js进程,则IPC通道的存在将启用process.send(),process.disconnect(),process.on(&#39; disconnect&#39;)和进程。 on(&#39; message&#39;)在孩子身上。

https://nodejs.org/api/child_process.html#child_process_options_stdio

只有在您正在产生的情况下,Node流程才会启用process.send()方法。

在您的情况下,您正在生成sudo进程,运行child.js的Node是sudo的参数,而不是从parent.js生成的。因此,process.send()无法启用,这就是为什么child.js会抛出错误。

因此child.send()实际上已按预期发送到sudo进程而不是node child.js

正如你在问为什么IPC不适用于sudo:我认为IPC正在运作。但是,如上所述,您正在尝试使用sudo进程进行IPC,该进程实际上无法理解或未能对您的child.send()操作做出回应。