Системы POSIX предоставляют семейство функций exec, которые позволяют загружать что-то, возможно, другое в текущий процесс, сохраняя дескрипторы открытых файлов, идентификатор процесса и так далее.

Это может быть сделано по разным причинам, и в моем случае это начальная загрузка - я хочу изменить параметры командной строки моего собственного процесса, а затем перезагрузить его поверх существующего процесса, чтобы не было дочерних процессов.

К сожалению, к моему большому удивлению, я не смог найти способ вызвать любую из exec* функций в Node.js. Итак, как правильно заменить текущий запущенный процесс Node.js другим образом?

1
toriningen 15 Дек 2015 в 16:22

3 ответа

Лучший ответ

Я создал модуль для вызова функции execvp из NodeJS: https://github.com/OrKoN/native- Exec

Это работает так:

var exec = require('native-exec');

exec('ls', {
  newEnvKey: newEnvValue,
}, '-lsa'); // => the process is replaced with ls, which runs and exits

Поскольку это аддон нативного узла, для него требуется установленный компилятор C ++. Прекрасно работает в Docker, на Mac OS и Linux. Возможно, не работает на Windows. Протестировано с узлами 6, 7 и 8.

3
Oleksii Rudenko 30 Июн 2017 в 11:28

Вот пример использования node-ffi, который работает с узлом v10. (увы, не v12)

#!/usr/bin/node

"use strict";

const ffi = require('ffi');
const ref = require('ref');
const ArrayType = require('ref-array');
const stringAry = ArrayType('string');

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('Login: ', (username) => {
    username = username.replace(/[^a-z0-9_]/g, "");
    rl.close();
    execvp("/usr/bin/ssh", "-e", "none", username+'@localhost');
});



function execvp() {
    var current = ffi.Library(null, 
                              { execvp: ['int', ['string',
                                                 stringAry]],
                                dup2: ['int', ['int', 'int']]});
    current.dup2(process.stdin._handle.fd, 0);
    current.dup2(process.stdout._handle.fd, 1);
    current.dup2(process.stderr._handle.fd, 2);
    var ret = current.execvp(arguments[0], Array.prototype.slice.call(arguments).concat([ref.NULL]));    
}
1
user1629060 13 Авг 2019 в 20:03

В итоге я использовал ffi модуль и экспортировал execvp из libc.

2
toriningen 29 Июн 2017 в 19:58