mix cmd (Mix v1.19.1)
View SourceExecutes the given command.
For example, you can invoke an external command such as make:
$ mix cmd make
Shell expansion
When you invoke mix cmd from the command line, environment variables,
glob patterns, and similar are expanded by the current shell and then
passed to mix cmd. For example, if you invoke:
$ mix cmd echo lib/*
Your shell will expand "lib/*" and then pass multiple arguments to
mix cmd, which in turn passes them to echo. Note that, mix cmd
by itself, does not perform any shell expansion. This means that,
if you invoke mix cmd programatically, as in:
Mix.Task.run("cmd", ["echo", "lib/*"])or through a mix.exs alias:
alias: "cmd echo lib/*"It will literally print "lib/*".
This behaviour is the default from Elixir v1.19. If you want
mix cmd to behave like a shell, you can pass the --shell
option before the command name:
Mix.Task.run("cmd", ["--shell", "echo", "lib/*"])Keep in mind however that, if --shell is given, quoted arguments
are no longer correctly propagated to the underlying command
(as they get expanded before hand).
This task is automatically re-enabled, so it can be called multiple times with different arguments.
Umbrella applications and directories
This task is also useful in umbrella applications to execute a command on each child app:
$ mix cmd pwd
In such cases, Mix will change the current working directory to the root of each umbrella application before executing the command.
You can limit which apps the cmd runs in by using mix do with the --app
option:
$ mix do --app app1 --app app2 cmd pwd
Note the tasks aborts whenever a command exits with a non-zero status.
Outside of umbrella projects, you can pass the --cd flag before the command,
to specify a directory:
$ mix cmd --cd "third-party" make
Command line options
--cd(since v1.10.4) - the directory to run the command in--shell(since v1.19.0) - perform shell expansion of the arguments
Orphan operating system processes
Beware that the Erlang VM does not terminate child processes
when it shuts down. Therefore, if you use mix cmd to start
long running processes and then shut down the VM, it is likely
that those child processes won't be terminated with the VM.
A solution is to make sure the child processes listen to the
standard input and terminate when standard input is closed.
We discuss this topic at length in the "Orphan operating system processes"
of the Port module documentation.