2017-07-20 3 views
0

J'essaie de définir une variable d'environnement lors de l'exécution d'une commande shell à l'aide de Port.open. . Il soulève une erreur, ArgumentError peu importe ce que je passeArgument Erreur lors de la tentative de spécification: env dans Elixir Port.open

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

Selon les docs Elixir pour Port.open, il doit accepter les arguments que la fonction Erlang: erlang.open_port accepte. La documentation Erlang mentionne:

{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)

Cette erreur se produit même si je tente d'appeler la fonction Erlang directement comme ceci:

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

L'erreur disparaît si je retire l'argument {:env, [{...}].

Répondre

4

L'option :env requiert que le nom et la valeur soient des chaînes Erlang, ce qui s'appelle une charlist dans Elixir, et est construite en utilisant des guillemets simples au lieu de doubles.

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

Source

Ce qui suit doit corriger l'erreur:

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

:args accepte les chaînes Erlang et Erlang binaires (Elixir Strings), de sorte que vous n'avez pas besoin de changer cela .

+0

Merci! Vous avez répondu à mes 3 dernières questions sur l'élixir: D. Existe-t-il un moyen plus facile de comprendre les erreurs comme ça? Le message d'erreur était si concis qu'il n'était presque pas utile. – you786

+0

Je suis d'accord que le message d'erreur n'est pas utile. Chaque fois que j'obtiens une erreur d'argument d'une fonction qui est dans la bibliothèque standard d'Erlang, je vérifie d'abord la signature de type de la fonction dans [docs] (http://erlang.org/doc/man/erlang.html#open_port-2) puis vérifiez si je passe des arguments du bon type. Si cela n'aide pas alors le dernier recours est de trouver le code source de la fonction et de voir ce que toutes les vérifications échouées conduisent à une erreur d'argument. – Dogbert