使用 sudo 生成的节点无法使用 ipc
node spawn with sudo cannot use ipc
在我的项目中,我需要创建一个子进程并通过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 一起使用吗?
尝试删除 所有 inherit
,IPC 应该可以工作。
请注意,您的代码不会打印 child 发送的 'hahaha' 消息,因为您没有等待或阻止;所以当你 运行 parent.js
时,它会执行每一行并安静地(干净地)退出。
如文档中所述:
If the child is a Node.js process, the presence of an IPC channel will enable process.send(), process.disconnect(), process.on('disconnect'), and process.on('message') within the child.
https://nodejs.org/api/child_process.html#child_process_options_stdio
只有在生成节点进程的情况下,才会启用 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()
操作做出响应。
在我的项目中,我需要创建一个子进程并通过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 一起使用吗?
尝试删除 所有 inherit
,IPC 应该可以工作。
请注意,您的代码不会打印 child 发送的 'hahaha' 消息,因为您没有等待或阻止;所以当你 运行 parent.js
时,它会执行每一行并安静地(干净地)退出。
如文档中所述:
If the child is a Node.js process, the presence of an IPC channel will enable process.send(), process.disconnect(), process.on('disconnect'), and process.on('message') within the child.
https://nodejs.org/api/child_process.html#child_process_options_stdio
只有在生成节点进程的情况下,才会启用 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()
操作做出响应。