如何让Escript使用用户的.erlang文件?Erlang 21环境问题
解决Escript不加载.erlang文件的问题
问题原因
Escript默认不会自动执行用户主目录下的.erlang文件,这和erl命令的行为存在差异——你的.erlang文件原本负责加载库的ebin路径,Escript跳过这一步后,自然找不到lager_app模块相关函数。
解决方案
方案1:在脚本中手动加载.erlang文件
直接在脚本开头添加代码,读取并执行.erlang文件内容:
#!/usr/bin/env escript %% -*- erlang -*- %%! -sname factorial -mnesia debug verbose % 手动加载用户主目录的.erlang文件 load_dot_erlang() -> HomeDir = case os:getenv("HOME") of false -> "."; Dir -> Dir end, DotErlang = filename:join(HomeDir, ".erlang"), case file:consult(DotErlang) of {ok, Terms} -> lists:foreach(fun(Term) -> eval_term(Term) end, Terms); {error, _} -> ok % 文件不存在或读取失败时忽略 end. eval_term(Term) -> case erl_scan:string(erl_parse:abstract(Term) ++ ".") of {ok, Tokens, _} -> case erl_parse:parse_exprs(Tokens) of {ok, Exprs} -> {value, _, _} = erl_eval:exprs(Exprs, erl_eval:new_bindings()); _ -> ok end; _ -> ok end. % 先执行加载逻辑 load_dot_erlang(), main([String]) -> try io:format("aaaa"), N = list_to_integer(String), F = fac(N), io:format("factorial ~w = ~w\n", [N,F]) catch _:_ -> usage() end; main(_) -> usage(). usage() -> io:format("aaaa\n~p",[lager_app:module_info()]), io:format("usage: factorial integer\n"), halt(1). fac(0) -> 1; fac(N) -> N * fac(N-1).
方案2:直接在启动参数中指定代码路径
如果你的.erlang核心作用是添加代码路径,可以直接在脚本的%%!行里用-pa或-pz参数指定lager的ebin目录:
%%! -sname factorial -mnesia debug verbose -pa /实际路径/lager/ebin
将/实际路径/lager/ebin替换为你本地lager编译后的ebin目录绝对路径。
方案3:用rebar3打包包含依赖的Escript(推荐)
如果用rebar3管理项目,可在rebar.config中配置让打包后的Escript自动包含依赖:
{escript_incl_apps, [lager]}. {escript_main_app, your_app_name}.
执行rebar3 escriptize生成可执行脚本,生成的文件会自动包含所有依赖模块,无需依赖.erlang文件加载路径。
验证
修改后重新运行脚本,应当能正常找到lager_app模块,不再抛出undefined function错误。
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

