POSIX系统提供了一系列exec
函数,允许将不同的东西加载到当前进程中,保持打开的文件描述符、进程标识符等等。
这可以出于各种原因进行,而在我的情况下,我想要引导——我想要更改自己进程的命令行选项,然后重新加载它到现有进程中,使其没有子进程。
不幸的是,令我非常惊讶的是,我找不到在Node.js中调用任何exec*
函数的方法。那么,用其他镜像替换当前正在运行的Node.js进程的正确方法是什么?
POSIX系统提供了一系列exec
函数,允许将不同的东西加载到当前进程中,保持打开的文件描述符、进程标识符等等。
这可以出于各种原因进行,而在我的情况下,我想要引导——我想要更改自己进程的命令行选项,然后重新加载它到现有进程中,使其没有子进程。
不幸的是,令我非常惊讶的是,我找不到在Node.js中调用任何exec*
函数的方法。那么,用其他镜像替换当前正在运行的Node.js进程的正确方法是什么?
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上运行。已测试过与node 6、7和8兼容。
以下是使用node-ffi的示例,可在node 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]));
}
ffi
模块,并将execvp
暴露给了进程。请记住,fork
不起作用,因为V8有线程,而fork()
系统调用只会复制主线程,所以分叉的解释器会立即崩溃。 - toriningenexecvp
。它不需要 ffi,而是编译为本地的 Node 插件。 - Oleksii Rudenko