【问题标题】:node spawn with sudo cannot use ipc带 sudo 的节点生成不能使用 ipc
【发布时间】:2017-03-08 10:11:12
【问题描述】:

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

代码如下:

文件: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!')

文件: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 一起使用吗?

【问题讨论】:

    标签: node.js ipc sudo spawn


    【解决方案1】:

    如文档中所述:

    如果子进程是 Node.js 进程,IPC 通道的存在将启用 process.send()、process.disconnect()、process.on('disconnect') 和 process.on('message' ) 在孩子体内。

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

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

    在您的情况下,您正在生成一个 sudo 进程,并且运行 child.js 的节点是 sudo 的参数,而不是从 parent.js 生成的。所以process.send() 不会启用,这就是 child.js 抛出错误的原因。

    所以child.send() 实际上被发送到sudo 进程,而不是预期的node child.js

    当您问为什么 IPC 不适用于 sudo 时:我认为 IPC 正在工作。但是,如上所述,您正在尝试使用 sudo 进程进行 IPC,而该进程实际上不理解或不会对您的 child.send() 操作做出响应。

    【讨论】:

      【解决方案2】:

      尝试删除 all inherits 和 IPC 应该可以工作。

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

      【讨论】:

      • 我试过了,但是IPC还是不行。如果我用process.execPath 替换sudo,那么IPC 就可以工作。我认为sudo 将分叉另一个子进程,就像:parent.js -&gt; sudo -&gt; child.js
      猜你喜欢
      • 2019-02-13
      • 2011-05-29
      • 2014-11-27
      • 1970-01-01
      • 2015-12-05
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      相关资源
      最近更新 更多