如何在关闭rebar3 shell前执行退出函数?
在Rebar3应用中实现Shell终止前执行指定函数
问题分析
你的代码存在语法错误(比如函数定义和消息匹配里的-应该是->),且没有正确关联到Shell终止的触发事件。要实现Shell终止前执行指定函数,核心是监控Shell对应的user进程——当Shell退出时,user进程会终止,通过捕获该进程的终止信号即可触发自定义逻辑。
可行方案实现
1. 编写监控进程模块
创建shell_cleanup.erl,实现监控user进程并执行清理逻辑的功能:
-module(shell_cleanup). -export([start_link/0]). start_link() -> Pid = spawn_link(fun monitor_shell/0), {ok, Pid}. monitor_shell() -> % 监控Shell对应的user进程 erlang:monitor(process, whereis(user)), receive {'DOWN', _Ref, process, _Pid, _Reason} -> % 执行Shell终止前的自定义操作 io:format("=== 开始执行Shell终止前的清理 ===~n"), do_custom_cleanup(), % 可选:终止整个应用 application:stop(your_app_name); _Other -> monitor_shell() end. % 替换为你的自定义清理逻辑 do_custom_cleanup() -> io:format("自定义清理操作完成:比如关闭资源、保存状态等~n").
2. 将监控进程加入Supervisor
修改应用的supervisor模块(例如your_app_sup.erl),把shell_cleanup作为子进程添加到监督树中:
-module(your_app_sup). -behaviour(supervisor). -export([start_link/0]). -export([init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1, period => 5}, ChildSpecs = [ #{id => shell_cleanup, start => {shell_cleanup, start_link, []}, restart => permanent, shutdown => 5000, type => worker, modules => [shell_cleanup]} ], {ok, {SupFlags, ChildSpecs}}.
3. 配置应用启动
确保src/your_app.app.src中指定了正确的启动模块:
{application, your_app_name, [{description, "你的Rebar3应用"}, {vsn, "0.1.0"}, {registered, [your_app_sup]}, {mod, {your_app, []}}, {applications, [kernel, stdlib ]}, {env,[]}, {modules, []}, {licenses, ["Apache-2.0"]}, {links, []} ]}.
4. 测试运行
- 编译应用:
rebar3 compile - 启动Shell:
rebar3 shell - 退出Shell(输入
q().或按Ctrl+C选择a),此时会看到自定义清理函数的输出
关键说明
user进程是Erlang Shell的核心进程,Shell终止时该进程会退出,通过监控它的DOWN消息可以精准捕获终止事件。- 将监控进程加入Supervisor,能保证应用启动时自动启动该进程,且异常退出时会被重启,确保监控逻辑持续生效。
- 如果不需要终止整个应用,可以去掉
application:stop(your_app_name),仅保留自定义清理逻辑即可。
内容的提问来源于stack exchange,提问作者Kaushik .p
相关产品推荐
相关产品推荐

