我是 Erlang 的新手,但我想知道是否有可能以某种方式附加到工作应用程序并检查它正在使用的 ETS 或 DETS。如果是,你愿意举一个小例子吗?
谢谢!
有两种方法可以做到这一点,这两种方法都可能有效,也可能无效,具体取决于 Erlang 节点的启动方式:
- 使用
to_erl
- 在 Erlang 发行版上打开一个远程外壳 (
erl -remsh
无论哪种方式,您最终都会得到一个 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
然后命令中的三个路径对应于:
- 保存命名管道的目录
- 记录标准输出的目录
- 用于实际启动 Erlang 节点的命令
你想要第一个用于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
但是,如果-name
或-sname
选项仅指定"裸"节点名称,则需要弄清楚它选择以哪个主机名开头:
erl -name myerlangnode # node name is actually myerlangnode@mymachine.example.com
erl -sname myerlangnode # node name is actually myerlangnode@mymachine
什么是饼干?
当一个 Erlang 节点连接到另一个节点时,两个节点都需要配置相同的"cookie",否则握手将失败。 可以从运行 Erlang 节点的用户的主目录中的文件.erlang.cookie
读取 cookie,也可以在启动节点时使用-setcookie
命令显式设置。
让我们连接!
所以现在我们知道:
- 正在运行的节点使用的确切节点名称
- 节点是以
-name
还是-sname
启动的(即长节点名称还是短节点名称) - Cookie 是从用户的主目录中读取的还是使用
-setcookie
设置
的
现在我们可以连接了! 我们需要启动一个临时的 Erlang 节点,该节点:
- 使用
-name
或-sname
,根据运行节点的启动方式 - 使用唯一的节点名称
- 要么使用与正在运行的节点相同的
-setcookie
选项,要么以同一用户身份运行以访问相同的.erlang.cookie
文件 - 使用
-remsh
("远程外壳")连接到正在运行的节点。 - 使用
-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 远程 shell 不起作用。
要退出,请键入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
的分布式节点。
如果您有权访问 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,您可以使用启动命令启动应用程序,并使用附加命令附加到正在运行的应用程序。您必须使用 Rebar3 发布才能使用这些命令。更多信息在这里。
样本:
rel/my_app/bin/my_app start
rel/my_app/bin/my_app attach
之后,按照上述操作访问 ETS 或使用 Erlang 手册页中列出的任何 ETS 命令。
使用 ctrl+D 进行分离。
混合搭配您可以使用常规erl -name temp@hostname
外壳连接到以 rebar3 启动的项目。只要 cookie 匹配并且您知道节点名称,就不必使用 Rebar3 附加到正在运行的应用程序。