从 Javascript(电子)执行 Erlang shell 命令不返回任何输出

Posted

技术标签:

【中文标题】从 Javascript(电子)执行 Erlang shell 命令不返回任何输出【英文标题】:Executing Erlang shell command from Javascript (Electron) is not returning any output 【发布时间】:2016-01-07 16:02:05 【问题描述】:

我正在尝试从 javascript 调用 Erlang 模块函数,但网页在 index.html 文件的 'erl_ver' div 元素中没有显示任何内容。

index.html

<!DOCTYPE html>
<html>
<head>
<title>App</title>
</head>
<body>
<h1>Welcome to App</h1>
<div id='erl_ver'></div> <div id='electron_ver'></script>.
<script type="text/javascript">
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/')) + "/";
var e = require('child_process');
e.exec('erl -noshell -s shell_info get_ver -s erlang halt',cwd: dir, function(err,stdout, stderr) 
    document.getElementById('erl_ver').innerHTML = "Erlang shell version: " + stdout;
    document.getElementById('electron_ver').innerHTML = ", Electron version: " + process.versions['electron'];
);
</script>
</body>
</html>

shell_info.erl

-module(shell_info).
-compile(export_all).

get_ver() ->
    io:format(erlang:system_info(system_version)).

但是,如果我从 javascript exec 函数中删除 cwd 选项,在 index.html 文件中,我会在网页上收到以下错误:

Erlang shell version: "init terminating in do_boot",undef,[shell_info,get_ver,[],[],init,start_it,1,[file,"init.erl",line,1054],init,start_em,1,[file,"init.erl",line,1034]]
, Electron version: 0.33.6

如何在网页上显示预期的 shell_info:get_ver() 输出?

预期输出:

C:\Users\eausaig\Downloads\electron-v0.33.6-win32-x64\erlang_studio>erl -noshell
 -s shell_info get_ver -s erlang halt
Erlang/OTP 18 [erts-7.1] [64-bit] [smp:4:4] [async-threads:10]

C:\Users\eausaig\Downloads\electron-v0.33.6-win32-x64\erlang_studio>

我修改了代码,在主进程中运行 exec 函数,然后使用 ipc 通信从渲染进程(网页)调用 exec 函数。我仍然收到上述相同的错误消息。使用 -pa 选项不会显示 shell_info:get_ver() 命令的输出:

ipc.on('erlang_version', function(event, arg) 
  var e = require('child_process');
  e.exec('erl -pa ' + __dirname + '-s shell_info get_ver -s erlang halt', function(err,stdout, stderr) 
  event.sender.send('erlang_version_response', stdout);
  );
);

添加了 -pa 选项的输出:

Erlang shell version:
, Electron version: 0.33.6

请注意,它适用于 Windows cmd 命令,例如 ver. 我将 'erl -pa ' + __dirname + '-s shell_info get_ver -s erlang halt' 替换为 'ver' 并显示输出。

Erlang shell version: Microsoft Windows [Version 6.1.7601]
, Electron version: 0.33.6

问题已解决。这是语法错误。我省略了 __dirname 和 '-s' 之间的空格。正确的语法应该是:

e.exec('erl -pa ' + __dirname + ' -s shell_info get_ver -s erlang halt', function(err,stdout, stderr) 

改正命令中的语法错误后的结果:

Erlang shell version: Erlang/OTP 18 [erts-7.1] [64-bit] [smp:4:4] [async-threads:10]
, Electron version: 0.33.6

【问题讨论】:

【参考方案1】:

Erlang 将根据代码路径查找 shell_info 模块(和任何其他模块)。如果您在当前目录中有一个梁文件,它会找到它,但您的网络服务器不会在那里找到它。

您可以通过使用erl的-pa参数来设置额外的代码路径,或者设置ERL_LIBS环境变量,或者您可以将您的模块安装在现有的默认代码路径中。

在我的系统上,默认的代码路径是“/usr/lib/erlang/lib”:

$ erl
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:8:8] [async-threads:0]     [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1> code:lib_dir().
"/usr/lib/erlang/lib"
2> 

请注意,如果您添加 PATH,它将在 PATH/X/ebin 中查找您的 shell_info.beam(其中 X 是任何东西(应该是 appname-version)。

【讨论】:

我已经尝试过 -pa 选项。它没有显示任何输出。网页 (index.html) 和 shell_info.beam 文件位于同一文件夹中。我在 Windows 7 上运行这个应用程序。 问题已修复。问题是语法错误。我在 e.exec('erl -pa ' + __dirname + ' -s shell_info get_ver -s erlang halt', function(err,stdout, stderr) 中省略了目录名称 (__dirname) 和 '-s' 选项之间的空格 干得好。同一目录中的 HTML 和 shell_info.beam 没有帮助,在这种情况下,重要的是 Web 服务器的 CWD,它不太可能是包含该 HTML 文件的目录。不确定 Windows,但在 Linux 上,“erl”是一个 shell 脚本,它设置一些变量并运行“erlexec”。如果 Windows 类似,您可以运行自己的前端脚本(而不是 erl)来设置 ERL_LIBS,并将其用于您的应用程序,或者为您的整个 Web 服务器进程设置 ERL_LIBS。如果您不想将模块安装在标准位置。这样你就不用到处复制那个路径了。

以上是关于从 Javascript(电子)执行 Erlang shell 命令不返回任何输出的主要内容,如果未能解决你的问题,请参考以下文章

erlang虚拟机代码执行原理

Erlang 脚本语言解释器

通过 Core Erlang 将 Erlang 编译为 Javascript

无法将 javascript 文件作为电子邮件附件发送

Erlang:从命令行调用 erl -eval 永远不会退出

如果能够并行执行很少的进程,那么能够有效地生成许多进程有什么意义呢?