System.getenv() prepends system path

My system path looks like this:
/bin:
/sbin:
/usr/bin:
/usr/sbin:
/usr/local/bin:
/opt/homebrew/bin:
/usr/local/mysql/bin:

When I ask Elixir for my path using System.get_env(“PATH”), Elixir prepends the ‘real’ path (above) with 1 or 2 ‘extra’ paths:
/opt/homebrew/Cellar/erlang/26.0.2/lib/erlang/erts-14.0.2/bin:
/opt/homebrew/Cellar/erlang/26.0.2/lib/erlang/bin:
/bin:
/sbin:
/usr/bin:
/usr/sbin:
/usr/local/bin:
/opt/homebrew/bin:
/usr/local/mysql/bin:

How do I tell Elixir to NOT prepend the returned path with the Erlang paths (I.E. return the path actually defined in my system)?

That is probably homebrew doing it no? So you can call Elixir/Erlang.

edit: no, see System.getenv() prepends system path - #4 by garazdawi

2 Likes

To me it looks like your system PATH looks like the second value. If it looked like the first value then you would not be able to start Erlang / Elixir at all.

Why do you think your system PATH is the first value?

When starting Erlang those two paths are prepended to PATH in order for the Erlang VM to be able to find the programs it needs to run properly. If you do not want them to be part of the PATH you will need to filter them out.

3 Likes

Thanks everyone for your help.

In the end, this is what I did:

  def get_path() do
    version = String.replace(elem(System.shell("ls $HOMEBREW_CELLAR/erlang"), 0), "\n", "")
    System.get_env("PATH")
    |> String.split(":")
    |> Enum.reject(fn x -> String.contains?(x, version) end)
    |> Enum.join(":")
  end

The downside to this solution is that if I install another, additional version of erl, I could potentially grab the wrong “version”… I’ll kick that can down the road for when it actually happens :wink:

I mean your code is already hardcoded the $HOMEBREW_CELLAR/erlang thing, why not just reject any path with THAT string in its name?

You could also only reject the matches until you hit a non-match (which would hopefully always be the ones elixir had prepended to your PATH).