создание узлов с помощью sudo не может использовать 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?


person yibn2008    schedule 08.03.2017    source источник


Ответы (2)


Как указано в документации:

Если дочерним процессом является процесс 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, а Node, на котором работает child.js, является аргументом для sudo, а не порождается из parent.js. Таким образом, process.send() не будет включен, Вот почему child.js выдает ошибку.

Таким образом, child.send() фактически отправляется процессу sudo вместо node child.js, как ожидалось.

Поскольку вы спрашиваете, почему IPC не работает для sudo: Я думаю, что IPC работает. Однако, как упоминалось выше, вы пытаетесь IPC с процессом sudo, который на самом деле не понимает или не отвечает на ваше действие child.send().

person ibigbug    schedule 08.03.2017

Попробуйте удалить все inherit, и IPC должно работать.

Имейте в виду, что ваш код не будет печатать сообщение «хахаха», которое отправляет ребенок, потому что вы не ждете и не блокируете; поэтому, когда вы запускаете parent.js, он выполняет каждую строку и тихо (и чисто) завершает работу.

person GPX    schedule 08.03.2017
comment
Я пробовал, но IPC все еще не работает. Если я заменю sudo на process.execPath, IPC будет работать. Я думаю, что sudo разветвит другой дочерний процесс, например: parent.js -> sudo -> child.js. - person yibn2008; 08.03.2017