如何在不退出IEx的情况下更新config.exs配置数据?
问题
修改了config.exs中Mechanics的ptz_port值(从"tty.usbserial-1420"改为"tty.usbserial-1410"),但在IEx中执行Application.get_all_env(Mechanics)查看时仍显示旧值。尝试调用Config.config_env()时出现RuntimeError报错,请问能否在IEx中通过命令更新配置而无需退出?
修改后的config.exs代码
import Config # config :logger, :console, format: "[$level] $metadata$message ", # metadata: [:module, :function, :my_id] config Mechanics, ptz_port: "tty.usbserial-1410", ptz_speed: 115200, ptz_check_interval: 5000
IEx查询结果
iex(16)> Application.get_all_env(Mechanics) [ ptz_check_interval: 5000, imu_speed: 115200, ptz_port: "tty.usbserial-1430", testkey1: "value1", imu_port: "tty.usbserial-1420", ptz_speed: 115200, imu_pose: "horizon", imu_check_interval: 5000, key2: "value2" ]
报错信息
iex(18)> Config.config_env() ** (RuntimeError) could not set configuration via Config. This usually means you are trying to execute a configuration file directly, instead of reading it with Config.Reader (elixir 1.13.4) lib/config.ex:91: Config.raise_improper_use!/0 (elixir 1.13.4) lib/config.ex:190: Config.__env__!/0
解决方案
1. 问题原因
Elixir应用启动时会加载并解析config.exs,配置一旦加载完成就固化在运行内存中,直接修改文件不会同步到当前IEx会话。另外,Config模块的核心函数是为编译时读取配置设计的,运行时调用会触发报错,这就是你看到RuntimeError的原因。
2. 无需退出IEx的配置更新方法
方式一:单条配置快速修改
如果只需要更新单个配置项,直接在IEx中执行:
Application.put_env(Mechanics, :ptz_port, "tty.usbserial-1410")
执行后再次调用Application.get_all_env(Mechanics),就能看到更新后的ptz_port值。
方式二:批量加载config.exs的所有修改
如果修改了多个配置项,想要一次性同步所有新配置,可以通过Config.Reader读取文件后批量更新:
# 读取config.exs的最新配置 configs = Config.Reader.read!("config.exs") # 遍历配置并更新到应用环境 Enum.each(configs, fn {app, app_config} -> Enum.each(app_config, fn {key, value} -> Application.put_env(app, key, value) end) end)
这种方式只会更新config.exs中定义的键,原有未修改的配置项(比如imu_port、testkey1等)会保留原值。
3. 注意事项
- 运行时修改的配置是临时的,应用重启后会恢复为
config.exs中的原始设置。 - 如果应用中有依赖该配置的进程(比如初始化时读取
ptz_port的进程),仅更新应用环境不会让这些进程自动加载新配置,需要手动重启对应进程才能生效。
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

