gpt4 book ai didi

bash - Erlang 和 bash 脚本(escript)

转载 作者:行者123 更新时间:2023-12-03 23:06:54 25 4
gpt4 key购买 nike

我是 Erlang 的新手,想将 bash 脚本与 Erlang 节点和函数合并。
我有一个 Mnesia 数据库,我们进入 Erlang 节点并运行几个函数,但我想通过一些 bash 脚本运行这些函数,以便我可以在其他地方使用这些 bash 脚本输出。
我的二郎 shell :-

sudo /opt/butler_server/bin/butler_server remote_console
Erlang/OTP 20 [erts-9.3.3.6] [source] [64-bit] [smp:28:28] [ds:28:28:10] [async-threads:10]

Eshell V9.3.3.6 (abort with ^G)
(butler_server@localhost)1>

在这个 shell 中,当我们运行下面的函数时,它运行良好并给出输出,请注意 order_node、pps_manager 是数据库中的模块名称,get_by_id、send_order_related_notification、update_status_of_order_node 是该模块中的函数。

f().

ChangeStatus =
fun() ->
{ok,C2}=order_node:search_by([{status,equal,inventory_awaited}],key),

io:format("Total Orders ~p", [length(C2)]),

lists:foreach(fun(Id) ->
io:format("Orders ~p~n", [Id]),
order_node:update_status_of_order_node(Id,cancelled),
pps_manager:send_order_related_notification(element(2,order_node:get_by_id(Id)))
end, C2)
end.

ChangeStatus().

请让我知道如何使用 bash 脚本在 erlang shell 中运行上面的代码片段。

最佳答案

当你使用 escript 时,你启动了一个新的 Erlang VM,所以如果你想真正连接到一个正在运行的节点,你需要使用类似 expect 的东西。 .

但是,您可以使用 escript 启动一个新节点并将其添加到正在运行的集群中,并借助 rpc module 中的方法。您可以在原始集群中运行代码:

假设您有一个以 erl -name main@127.0.0.1 -setcookie cookie 开头的节点,然后是脚本

#!/usr/bin/env escript
%%! -name escript@127.0.0.1 -hidden -setcookie cookie
main([RemoteNodeString]) ->
io:format("Escript node: ~p~n", [node()]),
RemoteNode = list_to_atom(RemoteNodeString),
io:format("~p's node(): ~p~n", [RemoteNode, rpc:call(RemoteNode, erlang, node, [])]),
io:format("~p's nodes(): ~p~n", [RemoteNode, rpc:call(RemoteNode, erlang, nodes, [])]),
ok.

将打印
$> ./test.escript main@127.0.0.1
Escript node: 'escript@127.0.0.1'
'main@127.0.0.1''s node(): 'main@127.0.0.1'
'main@127.0.0.1''s nodes(): []

(请注意,由于 -hidden flag,main 的节点列表是空的)。

除了他的 escript 没有运行任何有用的代码这一事实之外,这里还有三个问题:

1
escript 节点名称:由于 erlang 集群或同一主机中的名称必须是唯一的,如果 escript 有可能同时运行两次,这可能会出现问题。您可以通过生成一个随机名称来解决它(在 Erlang 或 bash 中,示例适用于 Erlang):
#!/usr/bin/env escript
%%! -hidden -setcookie cookie
main([RemoteNodeString]) ->
RandomTail = (<< <<($0 + rand:uniform(10)-1)>> || _ <- lists:seq(1,8) >>),
RandomName = binary_to_atom(<<"escript", RandomTail/binary, "@127.0.0.1">>, utf8),
io:format("Escript node: ~p~n", [RandomName]),
net_kernel:start([RandomName, longnames]),
RemoteNode = list_to_atom(RemoteNodeString),
io:format("~p's node(): ~p~n", [RemoteNode, rpc:call(RemoteNode, erlang, node, [])]),
io:format("~p's nodes(): ~p~n", [RemoteNode, rpc:call(RemoteNode, erlang, nodes, [])]),
io:format("~p's nodes(hidden): ~p~n", [RemoteNode, rpc:call(RemoteNode, erlang, nodes, [hidden])]),
ok.

$> ./test2.escript main@127.0.0.1 
Escript node: 'escript45560706@127.0.0.1'
'main@127.0.0.1''s node(): 'main@127.0.0.1'
'main@127.0.0.1''s nodes(): []
'main@127.0.0.1''s nodes(hidden): ['escript45560706@127.0.0.1']

但是,escript 节点的名称是一个原子,原子没有被 GC 处理,并且原子限制虽然非常高,但仍然存在。根据您的配置和使用模式,这对您来说可能是也可能不是问题。

2
原始节点名称和 cookie:连接到 main@127.0.0.1您需要知道名称,如果它以 long or short names 开头(如果主机部分有一个点,则需要长名称)和 cookie。此信息位于 vm.args文件(或在 shell 行中)。
如果没有设置 cookie,Erlang 会创建一个随机 cookie 并将其放在 $HOME 中。 .

3
与原始节点的网络连接:Erlang 分布式协议(protocol)需要 4369 端口(用于 EPMD )和节点范围(可用于配置 inet_dist_listen_mininet_dist_listen_max )可达。

准备好 escript 后,您可以从 bash 脚本调用它,也可以在调用 env escript 之前从 bash 脚本将其写入临时文件。在它上面( bash process substitution 不起作用,因为 escript 使用 file:position 并且进程替换是管道)。

关于bash - Erlang 和 bash 脚本(escript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62009886/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com