16

I'm working on a Erlang. How can I pass command line parameters to it?

Program File-

-module(program).
-export([main/0]).

main() ->
    io:fwrite("Hello, world!\n").

Compilation Command:

erlc Program.erl

Execution Command-

erl -noshell -s program main -s init stop

I need to pass arguments through execution command and want to access them inside main written in program's main.

Monti Chandra
  • 432
  • 5
  • 21

3 Answers3

21
$ cat program.erl
-module(program).
-export([main/1]).

main(Args) ->
    io:format("Args: ~p\n", [Args]).
$ erlc program.erl 
$ erl -noshell -s program main foo bar -s init stop
Args: [foo,bar]
$ erl -noshell -run program main foo bar -s init stop
Args: ["foo","bar"]

It is documented in erl man page.

I would recommend using escript for this purpose because it has a simpler invocation.

Hynek -Pichi- Vychodil
  • 26,174
  • 5
  • 52
  • 73
5

These are not really commandline-parameters, but if you want to use environment-variables, the os-module might help. os:getenv() gives you a list of all environment variables. os:getenv(Var) gives you the value of the variable as a string, or returns false if Var is not an environment-variable.

These env-variables should be set before you start the application.

I always use an idiom like this to start (on a bash-shell):

export PORT=8080 && erl -noshell -s program main
Mathias Vonende
  • 1,400
  • 1
  • 18
  • 28
5

If you want "named" argument, with possible default values, you can use this command line (from a toy appli I made):

erl -pa "./ebin" -s lavie -noshell -detach -width 100 -height 80 -zoom 6

lavie:start does nothing more than starting an erlang application:

-module (lavie).

-export ([start/0]).

start() -> application:start(lavie).

which in turn start the application where I defined default value for parameters, here is the app.src (rebar build):

{application, lavie,
 [
  {description, "Le jeu de la vie selon Conway"},
  {vsn, "1.3.0"},
  {registered, [lavie_sup,lavie_wx,lavie_fsm,lavie_server,rule_wx]},
  {applications, [
                  kernel,
                  stdlib
                 ]},
  {mod, { lavie_app, [200,50,2]}}, %% with default parameters
  {env, []}
 ]}.

then, in the application code, you can use init:get_argument/1 to get the value associated to each option if it was defined in the command line.

-module(lavie_app).

-behaviour(application).

%% Application callbacks
-export([start/2, stop/1]).

%% ===================================================================
%% Application callbacks
%% ===================================================================

start(_StartType, [W1,H1,Z1]) ->
    W = get(width,W1), 
    H = get(height,H1),
    Z = get(zoom,Z1),   
    lavie_sup:start_link([W,H,Z]).

stop(_State) ->
    % init:stop().
    ok.

get(Name,Def) ->
    case init:get_argument(Name) of
        {ok,[[L]]} -> list_to_integer(L);
        _ -> Def
    end.

Definitively more complex than @Hynek proposal, but it gives you more flexibility, and I find the command line less opaque.

Pascal
  • 13,977
  • 2
  • 24
  • 32