试图指定时参数错误:Elixir Port.open中的env

you*_*786 1 erlang elixir

我正在尝试使用运行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, [{...}]参数,错误就会消失.

Dog*_*ert 5

该: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字符串),因此您无需更改它.