2

我是 Erlang 的新手,但我想知道是否有可能以某种方式附加到工作应用程序并检查它正在使用的 ETS 或 DETS。如果是,你愿意举一个小例子吗?

谢谢!

4

2 回答 2

5

有两种方法可以做到这一点,根据 Erlang 节点的启动方式,这两种方法都可能起作用,也可能不起作用:

  • 使用to_erl
  • erl -remsh在 Erlang 发行版上打开一个远程 shell ( )

无论哪种方式,您最终都会得到一个 Erlang shell,您可以在其中检查您的表。


run_erl 和 to_erl

如果 Erlang 节点是使用run_erl包装器启动的,那么您可以使用to_erl. 您可以run_erl通过运行查看使用的命令:

ps -C run_erl -fww

例如,如果 Erlang 节点是使用以下命令启动的:

run_erl -daemon /my/erlang/node/tmp/ /my/erlang/node/log/ /my/erlang/node/start

那么命令中的三个路径分别对应:

  1. 保存命名管道的目录
  2. 记录标准输出的目录
  3. 实际启动 Erlang 节点的命令

你想要第一个 for to_erl,所以命令是:

to_erl /my/erlang/node/tmp/

注意尾部的斜线!to_erl如果丢失,会感到困惑。

要退出,请键入Ctrl-D


使用 Erlang 发行版连接

如果 Erlang 节点作为分布式节点运行,并且您知道秘密“cookie”,则可以启动另一个节点并打开远程 shell。

哪个节点名称?长还是短?

您需要知道正在运行的节点的节点名称,以及它是以“长”还是“短”节点名称运行的。

在“长”节点名中,主机部分是完全限定的域名或 IP 地址,但在“短”节点名中,主机部分只是主机名,没有点。如果 Erlang 节点以-name选项启动,则它使用长节点名称,如果以-sname选项启动,则使用短节点名称。如果两个选项都没有使用,则它不是分布式节点,并且无法连接到它。1

主机名在命令中可能是显式或隐式的。如果命令看起来像其中之一,则您已经知道确切的节点名称:

erl -name myerlangnode@mymachine.example.com
erl -sname myerlangnode@mymachine

但如果-nameor-sname选项仅指定“裸”节点名称,则您需要确定它选择以哪个主机名开头:

erl -name myerlangnode    # node name is actually myerlangnode@mymachine.example.com
erl -sname myerlangnode   # node name is actually myerlangnode@mymachine

什么是饼干?

当一个 Erlang 节点连接到另一个节点时,两个节点需要配置相同的“cookie”,否则握手将失败。cookie 可以从.erlang.cookie运行 Erlang 节点的用户的主目录中的文件中读取,也可以-setcookie在启动节点时使用命令显式设置。

让我们连接!

所以现在我们知道了:

  • 运行节点使用的确切节点名称
  • 节点是否以-nameor开头-sname(即长节点名或短节点名)
  • cookie 是从用户的主目录读取还是设置为-setcookie

现在我们可以连接了!我们需要启动一个临时的 Erlang 节点:

  • 使用-nameor -sname,根据运行节点的启动方式
  • 使用唯一的节点名称
  • 要么使用与-setcookie运行节点相同的选项,要么以同一用户身份运行以访问同一.erlang.cookie文件
  • 使用-remsh("remote shell") 连接到正在运行的节点。
  • 用于-hidden避免被视为 Erlang 集群的一部分

所以是这样的:

erl -hidden -name mytmpnode -setcookie secret -remsh myerlangnode@mymachine.example.com
erl -hidden -sname mytmpnode -setcookie secret -remsh myerlangnode@mymachine

这应该在正在运行的节点上打开一个 shell。您可以通过查看提示来判断,它应该告诉您节点名称:

(myerlangnode@mymachine)1>

如果它没有显示正确的节点名称,请参阅问题Erlang remote shell not working

要退出,请键入Ctrl-g,然后q


检查 ETS 或 DETS 表

一旦有了 Erlang shell,就可以检查表。使用ets:all()dets:all()列出现有表。对于 ETS,您可以使用ets:tab2list,它在表格中显示所有条目:

ets:tab2list(my_table).

对于 DETS,您可以使用dets:match_object通配符'_'模式:

dets:match_object(my_table, '_').

1除非该节点最初是作为非分布式节点,后来变成分布式节点net_kernel:start

于 2018-01-15T10:40:41.607 回答
1

如果您有权访问,您可以使用 Observer 查看 ETS 表。从 erlang shell 只需键入observer:start().即可打开 GUI。

要连接到正在运行的命名节点,请使用 Erlang Shell 中的连接到远程节点选项。

启动命名节点

$erl -name application@hostname

从不同的机器或终端启动一个新的 erlang shell

$erl -name temp@hostname

从您的临时 erlang shell 中按 Ctrl+g 连接到应用程序,然后按h?以获取选项列表。选项r是连接到远程节点并c连接到新作业。

>r 'application@hostname'
>c

之后,您可以像在该机器上一样调用任何命令,调用任何模块:函数,并访问 ETS 表。

如果您在同一台机器上,则没有其他内容,如果您在不同的机器上,则必须设置 cookie 以使它们匹配,否则您将无法连接。

断开连接时要小心,在退出之前必须切换到本地节点,或者杀死临时应用程序,不要杀死真正的应用程序。

钢筋3

现在很多人使用 Rebar3 来创建和运行 Erlang 项目,如果你不这样做,我强烈推荐使用它。

使用 Rebar3,您可以使用 start 命令启动应用程序,并使用 attach 命令附加到正在运行的应用程序。您必须使用 Rebar3 发布才能使用这些命令。更多信息在这里

样本:

rel/my_app/bin/my_app start
rel/my_app/bin/my_app attach

之后按照上述方法访问 ETS 或使用erlang 手册页中列出的任何 ets 命令。

使用 ctrl+D 分离。

混合搭配erl -name temp@hostname您可以使用常规shell 连接到以 rebar3 开始的项目。只要 cookie 匹配并且您知道节点名称,您就不必使用 Rebar3 附加到正在运行的应用程序。

于 2018-01-17T02:42:04.953 回答