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

时间:2017-07-20 18:19:56

标签: erlang elixir

我正在尝试使用Port.open运行shell命令时设置环境变量。无论我传递什么,它都会引发错误ArgumentError

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

根据Port.open的Elixir文档,它应该接受Erlang函数:erlang.open_port接受的任何参数。 Erlang文档提到:

  

{env,Env}仅对{spawn,Command}和{spawn_executable,   文件名}。启动过程的环境使用扩展   环境中的环境规范

     

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"]}])

如果删除{:env, [{...}]参数,则错误消失。

1 个答案:

答案 0 :(得分:5)

:env选项要求名称和值都是Erlang字符串,在Elixir中称为charlist,并使用单引号而不是double来构造。

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

Source

以下内容应修复错误:

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

:args接受Erlang字符串和Erlang二进制文件(Elixir Strings),因此您不需要更改它。