you786
you786

Reputation: 3540

Argument Error when trying to specify :env in Elixir Port.open

I'm trying to set an environment variable when running a shell command using Port.open. It raises an error, ArgumentError no matter what I pass in.

port = Port.open({ :spawn_executable, "/usr/local/bin/cool" },
        [:stream, :in, :binary, :eof, :hide, 
          {:env, [{"COOL_ENV", "cool"}]},
          { :args, ["test.js"] }])

According to the Elixir docs for Port.open, it should accept any arguments that the Erlang function :erlang.open_port accepts. The Erlang documentation mentions:

{env, Env} Only valid for {spawn, Command}, and {spawn_executable, FileName}. The environment of the started process is extended using the environment specifications in Env.

Env is to be a list of tuples {Name, Val}, where Name is the name of an environment variable, and Val is the value it is to have in the spawned port process. Both Name and Val must be strings. The one exception is Val being the atom false (in analogy with os:getenv/1, which removes the environment variable. (http://erlang.org/doc/man/erlang.html#open_port-2)

This error occurs even if I try to call the erlang function directly like so:

:erlang.open_port({:spawn_executable, "/usr/local/bin/cool"}, [:stream, :in, :binary, :eof, :hide, {:env, [{"COOL", "cool"}] },{:args, ["test.js"]}])

The error goes away if I remove the {:env, [{...}] argument.

Upvotes: 2

Views: 971

Answers (1)

Dogbert
Dogbert

Reputation: 222040

The :env option requires both the name and the value to be Erlang strings, which is called a charlist in Elixir, and is constructed using single quotes instead of double.

Opt =
    ...
    {env, Env :: [{Name :: string(), Val :: string() | false}]} |
    ...

Source

The following should fix the error:

port = Port.open({ :spawn_executable, "/usr/local/bin/cool" },
        [:stream, :in, :binary, :eof, :hide, 
          {:env, [{'COOL_ENV', 'cool'}]},
          { :args, ["test.js"] }])

:args accepts both Erlang strings and Erlang binaries (Elixir Strings), so you don't need to change that.

Upvotes: 7

Related Questions