【问题标题】:How to run Erlang from unix shell with complex params?如何从具有复杂参数的 unix shell 运行 Erlang?
【发布时间】:2011-05-30 08:34:48
【问题描述】:

我需要从 unix shell 运行复杂的 Erlang 模块函数

rpc:call('node@example.com', mnesia, dirty_first, [mytable])

我该怎么做?

更新:

我让test.escript

chmod +x test.escript

#!/usr/lib64/erlang/bin/escript
%%! -name 'test@example.com'
main(_Args) ->
    R = rpc:call('node@example.com', mnesia, dirty_first, [mytable]),
    io:format("~p~n",[R]).

并接收{badrpc, nodedown}

但是当运行时

erl -name test@example.com
1> rpc:call('node@example.com', mnesia, dirty_first, [mytable]).
{my, data}.

我的意思是它可以工作,但是如何使 escript 正常工作?

【问题讨论】:

    标签: erlang


    【解决方案1】:

    你可以用escript解析复杂的参数:

    #!/usr/bin/env escript
    
    main(String) ->
      {Node, Mod, Fun, Args} = parse_args(String),
      R = rpc:call(Node, Mod, Fun, Args),
      io:format("~p~n",[R]).
    

    【讨论】:

    • {badrpc,nodedown} 但 'node@example.com' 正在运行
    • 我已经编辑了我的帖子并添加了一些可能解决这个 badrpc 问题的示例。
    【解决方案2】:

    我认为escript 可能值得研究。

    编辑: 一些例子。

    首先是所有示例:以某种方式在某处启动远程节点。

                dannib@duval:~:> erl -sname bar
                (bar@duval)1> erlang:get_cookie().
                'KNKKCFPYMJUPIOLYPOAA'
    

    脚本

    1:用内容创建一个名为hello.escript的文件

                #!/usr/bin/env escript
                %%! -sname foo@duval -setcookie KNKKCFPYMJUPIOLYPOAA
    
                main(_String) ->
                    Node = 'bar@duval',
                    Mod = 'erlang',
                    Fun = 'node', 
                    Args = [], 
                        R = rpc:call(Node, Mod, Fun, Args),
                    io:format("Hello there ~p~n",[R]).
    

    注意%%! -sname foo@bar 标识主机上的节点(而不是创建nonode@nohost),允许将相同的cookie %%! -sname foo@duvel -setcookie KNKKCFPYMJUPIOLYPOAA 设置为目标主机,这解决了获取{badrpc,nodedown} 的问题。请注意,相同的语句适用于以下示例(erl_call 和 -eval),其中设置了节点名称和 cookie。

    2:设置执行位并运行

                $ chmod +x hello.escript
                $ ./hello.escript 
                Hello there bar@duval
    

    Erl_call

    1:运行

                $ erl_call -c 'KNKKCFPYMJUPIOLYPOAA' -a 'erlang node' -n bar@duval
                bar@duval
    

    评估

    1:运行

                $ erl -sname foo -setcookie 'KNKKCFPYMJUPIOLYPOAA' 
                -eval 'io:format("Hello there ~p~n",[rpc:call(bar@duval,erlang, node, [])])'
                ... Eshell V5.7.4  (abort with ^G)
                (foo@duval)1> Hello there bar@duval
    

    这会创建一个外壳,在这种情况下可能不是您想要的。

    我可能会提到,如果两个节点位于同一主机上并使用相同的 cookie 默认值,则不必像示例中那样显式设置 foo 和 bar 的 cookie 值。

    在完成这些示例并再次阅读您的问题之后,我认为我给出的糟糕建议将是您的最佳选择,erl_call。我喜欢问题标题中的“复杂”一词,恕我直言,脚本允许以易于阅读的方式进行更多“复杂”设置。 escript 示例中的变量_String 保存脚本的参数,它允许您通过shell 访问输入并在EVM 中执行复杂的erlang 操作。但是,如果您已经在其他应用程序中拥有逻辑并且只需要对 erlang 节点进行这个简单的调用,则 erl_call 可能会更直接。

    【讨论】:

      【解决方案3】:

      你可以使用erl的-eval标志:

      $ erl -eval 'io:format("Hello, World!~n")'
      

      【讨论】:

        【解决方案4】:

        erl_call 应用正是您所需要的:

        erl_call 可以启动和/或与分布式 Erlang 节点通信。它建立在 erl_interface 库之上,作为示例应用程序。其目的是使用 Unix shell 脚本与分布式 Erlang 节点进行交互。它使用标准的 Erlang RPC 工具执行与 Erlang rex 服务器的所有通信。它不需要在 Erlang 目标节点上运行任何特殊软件。

        主要用途是启动分布式 Erlang 节点或进行普通函数调用。但是,也可以通过管道将 Erlang 模块传递给 erl_call 并对其进行编译,或者通过管道传递一系列要评估的 Erlang 表达式(类似于 Erlang shell)。

        查看示例了解更多详情

        【讨论】:

          【解决方案5】:

          如果您的问题是如何在网络模式下设置 Erlang 节点(即将节点变成分布式节点),您可能想做类似的事情

          EPMD = code:root_dir() ++ "/bin/epmd &",
          os:cmd(EPMD),
          net_kernel:start([Sname, shortnames])
          

          其中 Sname 是您想要的节点名称。只有在此之后,您才能开始与另一个节点通信,例如RPC。

          【讨论】:

            猜你喜欢
            • 2020-12-06
            • 2012-12-14
            • 2010-10-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多