在Node.js中调用execl、execle、execlp、execv、execvP或execvp的方法

4

POSIX系统提供了一系列exec函数,允许将不同的东西加载到当前进程中,保持打开的文件描述符、进程标识符等等。

这可以出于各种原因进行,而在我的情况下,我想要引导——我想要更改自己进程的命令行选项,然后重新加载它到现有进程中,使其没有子进程。

不幸的是,令我非常惊讶的是,我找不到在Node.js中调用任何exec*函数的方法。那么,用其他镜像替换当前正在运行的Node.js进程的正确方法是什么?


请考虑以下问题:https://dev59.com/r2865IYBdhLWcg3wCqBA - clay
@toriningen,你找到解决方案了吗? - Oleksii Rudenko
@OleksiiRudenko,是的。我使用了ffi模块,并将execvp暴露给了进程。请记住,fork不起作用,因为V8有线程,而fork()系统调用只会复制主线程,所以分叉的解释器会立即崩溃。 - toriningen
我明白了。我自己没有找到现成的解决方案,所以我创建了这个模块 https://github.com/OrKoN/native-exec 来调用 execvp。它不需要 ffi,而是编译为本地的 Node 插件。 - Oleksii Rudenko
1
@OleksiiRudenko 请把这个转化为答案,我会接受它。 - toriningen
显示剩余6条评论
3个回答

3
我已经创建了一个模块,可以从NodeJS中调用execvp函数: 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上运行。已测试过与node 6、7和8兼容。


我猜在Windows中它不应该工作,除非在LXSS中启动。 - toriningen

3

以下是使用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]));    
}

2

我最终使用了ffi模块,并从libc中导出了execvp


1
请问您能分享一下您用来完成这个任务的代码吗?谢谢。 - TrevTheDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接