Running an Elixir File as a Script
Elixir is able to run “scripts” or files that are compiled into memory (not on disk) and executed. This is helpful when experimenting with larger Elixir code snippets. This is also helpful if you just want to occasionally run one-off scripts to perform some work and exit.
File: my_test_script.exs
defmodule MyTestScript do
def say_hi do
IO.puts "Hello!"
end
end
MyTestScript.say_hi
To execute the file, from a command-line in the same directory as the file, you can run:
$ elixir my_test_script.exs
Hello!
The output “Hello!” is displayed in the terminal.
What Just Happened?
This does the following things:
- A BEAM instance is started
- The file
my_test_script.exs
is loaded and compiled in memory. The interpreted symbols are loaded into the VM. - The code after the module, (i.e.
MyTestScript.say_hi
) is interpreted and run. - After completing execution, the BEAM instance is shutdown.
File Extension .exs
?
The file extension used on the file is .exs
. A normal Elixir file that is compiled ends in .ex
. The “s” denotes it is a script and should be interpreted at runtime and not compiled.
Files ending in .exs
are also used for writing your test files, project configuration files, database migrations and custom scripts. After all, you don’t want your unit test code to be compiled into your deployed project!
Downsides
There are several downsides with building any significant amount of source code using .exs
script files.
- They aren’t as performant. They must be “compiled” again each time they are run.
- As a project grows, you want to break it out into multiple files for code organization and your own sanity. When running as a script, it is difficult to load and include those other files. However, you can do it. I just don’t recommend it.
- If your code starts some concurrent tasks, the new processes will spawn and the BEAM promptly shuts down because it completed all the statements you gave it to execute. You can tell the runtime to keep it going using
elixir --no-halt my_test_script.exs
. To exit, hitCTRL+C, CTRL+C
(yup, 2 times) to kill the running BEAM instance.
Mix Project Alternative
A better approach that’s easy to do and will grow with you as you experiment is creating a new mix project.
3 Comments
Leave a Comment
You must be logged in to post a comment.
I have the following error in the Visual Studio Code when create exs script, it appears several times in OUTPUT logs. The script runs without errors though.
Starting ElixirLS release v0.14.3
Running in d:/Projects/Elixir/sandbox
** (Mix.Error) Could not find an SCM for dependency :sourceror from ElixirLS.LanguageServer.Mixfile
(mix 1.14.4) lib/mix.ex:513: Mix.raise/2
(mix 1.14.4) lib/mix/dep/loader.ex:195: Mix.Dep.Loader.with_scm_and_app/4
(mix 1.14.4) lib/mix/dep/loader.ex:141: Mix.Dep.Loader.to_dep/3
(elixir 1.14.4) lib/enum.ex:1658: Enum.”-map/2-lists^map/1-0-“/2
(elixir 1.14.4) lib/enum.ex:1658: Enum.”-map/2-lists^map/1-0-“/2
(mix 1.14.4) lib/mix/dep/loader.ex:358: Mix.Dep.Loader.mix_children/2
(mix 1.14.4) lib/mix/dep/loader.ex:316: anonymous fn/4 in Mix.Dep.Loader.mix_dep/2
(mix 1.14.4) lib/mix/project.ex:397: Mix.Project.in_project/4
[Error – 4:44:08 PM] Server initialization failed.
Message: Pending response rejected since connection got disposed
Code: -32097
[Info – 4:44:09 PM] Connection to server got closed. Server will restart.
true
[Error – 4:44:09 PM] ElixirLS – sandbox client: couldn’t create connection to server.
Message: Pending response rejected since connection got disposed
Code: -32097
Hi @vlhardy!
The VS Code extension Elixir “ElixirLS: Elixir support and debugger” is what’s complaining there. If you were to run the script in a terminal outside of VS Code, you wouldn’t see that error message.
You may need to update the plugin or there may be some other configuration issue. You can spot it by `ElixirLS.LanguageServer`. That’s the ElixirLS code completion engine complaining. I wonder if it complains because the single-file script isn’t a mix project? Hmm.
Hi Mark!
Thank you for the quick reply. Indeed, the issue was related to the “ElixirLS: Elixir support and debugger” extension. I was testing my_test_script.exs from the example above.
Fortunately, it was resolved with ChatGPT help) It suggested to run the following in the terminal:
mix local.hex && mix local.rebar && mix hex.info elixir_ls
And it helped! So, the issue is solved.