我正在尝试使用运行shell命令时设置环境变量Port.open.ArgumentError无论我传递什么,它都会引发错误.
port = Port.open({ :spawn_executable, "/usr/local/bin/cool" },
[:stream, :in, :binary, :eof, :hide,
{:env, [{"COOL_ENV", "cool"}]},
{ :args, ["test.js"] }])
Run Code Online (Sandbox Code Playgroud)
根据Port.open的Elixir文档,它应该接受Erlang函数:erlang.open_port接受的任何参数.Erlang文档提到:
{env,Env}仅对{spawn,Command}和{spawn_executable,FileName}有效.使用Env中的环境规范扩展启动过程的环境.
Env是一个元组列表{Name,Val},其中Name是环境变量的名称,Val是它在生成的端口进程中的值.Name和Val都必须是字符串.唯一的例外是Val是原子假(类似于os:getenv/1,它删除了环境变量.(http://erlang.org/doc/man/erlang.html#open_port-2)
即使我尝试直接调用erlang函数,也会发生此错误:
:erlang.open_port({:spawn_executable, "/usr/local/bin/cool"}, [:stream, :in, :binary, :eof, :hide, {:env, [{"COOL", "cool"}] },{:args, ["test.js"]}])
Run Code Online (Sandbox Code Playgroud)
如果我删除{:env, [{...}]参数,错误就会消失.
该:env选项要求名称和值都是Erlang字符串,在Elixir中称为charlist,并使用单引号而不是double构造.
Opt =
...
{env, Env :: [{Name :: string(), Val :: string() | false}]} |
...
Run Code Online (Sandbox Code Playgroud)
以下应该修复错误:
port = Port.open({ :spawn_executable, "/usr/local/bin/cool" },
[:stream, :in, :binary, :eof, :hide,
{:env, [{'COOL_ENV', 'cool'}]},
{ :args, ["test.js"] }])
Run Code Online (Sandbox Code Playgroud)
:args 接受Erlang字符串和Erlang二进制文件(Elixir字符串),因此您无需更改它.