在Elixir中,有没有办法直接从shell调用模块函数,而不需要启动iex -S mix会话?让我用一个场景来说明:
作为我的Phoenix应用程序的一部分,我编写了一个辅助模块,可以从相邻的iex -S mix会话中运行.这是一个超级简化的版本:
defmodule MyApp.Helper do
# For the demo, these imports/aliases are not used - but they're there in real life.
import Ecto.Query
alias MyApp.Repo
def start do
{:ok, "Done"}
end
end
Run Code Online (Sandbox Code Playgroud)
如果我启动会话iex -S mix然后从模块运行一个函数,它一切正常:
$ iex -S mix
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 2 files (.ex)
Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> MyApp.Helper.start
{:ok, "Done"}
Run Code Online (Sandbox Code Playgroud)
然后ctrl-c a关闭会话.
但是,如果我尝试这样的事情:
$ iex -S mix MyApp.Helper.start
Run Code Online (Sandbox Code Playgroud)
这导致了
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 2 files (.ex)
** (Mix) The task "MyApp.Helper.start" could not be found
Run Code Online (Sandbox Code Playgroud)
或者,我尝试将我的模块重新定义为自定义混合任务,如下所述:https://elixirschool.com/en/lessons/basics/mix-tasks/#custom-mix-task
但这也失败了,因为我的模块依赖于某些导入/别名MyApp.Repo,并试图用任一个mix helper或iex -S mix helper导致执行该文件
** (ArgumentError) repo MyApp.Repo is not started, please ensure it is part of your supervision tree
Run Code Online (Sandbox Code Playgroud)
如果没有办法解决这个问题并且脚本只能在运行中成功执行iex -S mix,那很好......但如果有办法设置,那么可以从shell运行一个单行程来执行此操作需要的,那就是蜜蜂的膝盖.
Dog*_*ert 12
您可以使用mix run与-e该参数:
$ mix run -e MyApp.Helper.start
Run Code Online (Sandbox Code Playgroud)
或者如果你有参数传递给函数:
$ mix run -e "MyApp.Helper.start(:foo, :bar)"
Run Code Online (Sandbox Code Playgroud)
来自mix help run:
如果希望在当前应用程序中执行脚本或通过命令行标志配置应用程序,则可以通过将脚本文件或eval表达式传递给命令来执行此操作:
Run Code Online (Sandbox Code Playgroud)mix run my_app_script.exs arg1 arg2 arg3 mix run -e "MyApp.start" -- arg1 arg2 arg3