在 escript 中使用 os:cmd 启动 Erlang 应用程序失败。

Using os:cmd to in escript to start Erlang application fails.

我有一个名为 tb 的 Erlang 应用程序,通过执行 application:start(tb) 从 Erlang 命令行 运行 没问题。而当我尝试使用 os:cmd 从 escript 内部调用同一个应用程序时,该应用程序似乎没有 运行。当我执行 'ps | grep beam' 时,我看到 beam.smp 进程 运行ning。但是应用程序没有生成任何 output.What 可能是问题所在?有没有更好的方法从 escript 内部启动另一个 erlang VM?

这是代码片段:

net_kernel:start([tb_escript, shortnames]),
read_config_file(FName),
Cookie = get(cookie),
Node = get(node),
N = io_lib:format("~p",[Node]),
lists:flatten(N),
C = io_lib:format("~p",[Cookie]),
lists:flatten(C),
EBIN = "~/tb/ebin",
erlang:set_cookie(tb_escript,Cookie), 
os:cmd("erl -pa " ++ EBIN ++ " -sname " ++ N ++ " -detached " ++ " -setcookie " ++ C ++ " -s application start tb").

发生这种情况是因为 -s 的 args 标志将参数包装在列表中并将其传递给 module:function/1-s application start tb 将执行 application:start([tb]),这将 return {error,{bad_application,[ssl]}}。因为这只是一个正常的 return 值,所以 erl.

不会打印错误

来自erl documentation:

-s Mod [Func [Arg1, Arg2, ...]](init flag)

Makes init call the specified function. Func defaults to start. If no arguments are provided, the function is assumed to be of arity 0. Otherwise it is assumed to be of arity 1, taking the list [Arg1,Arg2,...] as argument. All arguments are passed as atoms.

有两种方法可以解决这个问题:

  1. 使用 -eval "application:start(tb)",正如您在评论中提到的那样。

  2. 向调用 application:start(tb)tb 添加一个 start/0(如果尚未存在)函数,然后仅将 -s tb 传递给 erl-s 使用单个参数将调用 module:start().