Запустить erlang из оболочки unix со сложными параметрами

Мне нужно запустить сложную функцию модуля Erlang из оболочки Unix

rpc:call('node@example.com', mnesia, dirty_first, [mytable])

как мне это сделать?

UPD:

я делаю test.escript

chmod +x test.escript

#!/usr/lib64/erlang/bin/escript
%%! -name 'test@example.com'
main(_Args) ->
    R = rpc:call('node@example.com', mnesia, dirty_first, [mytable]),
    io:format("~p~n",[R]).

и получить {badrpc, nodedown}

но когда беги

erl -name test@example.com
1> rpc:call('node@example.com', mnesia, dirty_first, [mytable]).
{my, data}.

Я имею в виду, что это работает, но как заставить escript работать правильно?

5 ответов

Решение

Я думаю, что escript может быть чем-то стоящим.

Изменить: несколько примеров.

Сначала для всех примеров: как-нибудь запустить удаленный узел где-нибудь.

            dannib@duval:~:> erl -sname bar
            (bar@duval)1> erlang:get_cookie().
            'KNKKCFPYMJUPIOLYPOAA'

Escript

1: создать файл с именем hello.escript с содержанием

            #!/usr/bin/env escript
            %%! -sname foo@duval -setcookie KNKKCFPYMJUPIOLYPOAA

            main(_String) ->
                Node = 'bar@duval',
                Mod = 'erlang',
                Fun = 'node', 
                Args = [], 
                    R = rpc:call(Node, Mod, Fun, Args),
                io:format("Hello there ~p~n",[R]).

Обратите внимание, что %%! -sname foo@bar идентифицирует узел на хосте (вместо создания nonode@nohost), разрешите установку того же куки %%! -sname foo@duvel -setcookie KNKKCFPYMJUPIOLYPOAA в качестве целевого хоста, который решает проблему получения {badrpc,nodedown}, Обратите внимание, что то же самое утверждение справедливо для следующих примеров (erl_call и -eval), где заданы как имя узла, так и cookie.

2: установить бит выполнения и запустить

            $ chmod +x hello.escript
            $ ./hello.escript 
            Hello there bar@duval

Erl_call

1: запустить

            $ erl_call -c 'KNKKCFPYMJUPIOLYPOAA' -a 'erlang node' -n bar@duval
            bar@duval

Eval

1: запустить

            $ erl -sname foo -setcookie 'KNKKCFPYMJUPIOLYPOAA' 
            -eval 'io:format("Hello there ~p~n",[rpc:call(bar@duval,erlang, node, [])])'
            ... Eshell V5.7.4  (abort with ^G)
            (foo@duval)1> Hello there bar@duval

Это создает оболочку, которая может быть не тем, что вы хотите в этом случае.

Я мог бы упомянуть, что если оба узла находятся на одном и том же хосте и используют одно и то же значение cookie по умолчанию, то значение cookie для foo и bar не нужно явно устанавливать, как в примерах.

После выполнения этих примеров и повторного прочтения вашего вопроса, я думаю, что то, что я дал ДАЖЕ, сказал ваш лучший выбор, erl_call. Я попал на слово "сложный" в названии вопроса, где имхо-сценарии позволяют легко и просто читать более "сложные" настройки. Переменная _String в примере escript содержит аргументы скрипта, который позволяет как получить доступ к вводу через оболочку, так и выполнить сложные операции erlang в EVM. Но erl_call может быть более простым, если у вас уже есть логика в каком-то другом приложении, и вам просто нужно сделать этот простой вызов узла erlang.

Приложение erl_call - это именно то, что вам нужно:

erl_call позволяет запускать и / или связываться с распределенным узлом Erlang. Он построен на библиотеке erl_interface в качестве примера приложения. Его целью является использование сценария оболочки Unix для взаимодействия с распределенным узлом Erlang. Он выполняет всю связь с сервером Erlang Rex, используя стандартное средство RPC Erlang. На целевом узле Erlang не требуется никакого специального программного обеспечения.

Основное использование - либо запустить распределенный узел Erlang, либо сделать обычный вызов функции. Тем не менее, также возможно передать модуль Erlang в erl_call и скомпилировать его, или передать последовательность выражений Erlang для оценки (аналогично оболочке Erlang).

Смотрите примеры для более подробной информации

Вы можете использовать -eval флаг erl:

$ erl -eval 'io:format("Hello, World!~n")'

Если ваша проблема заключается в том, как настроить узел Erlang в сетевом режиме (т.е. превратить узел в распределенный узел), вы можете сделать что-то вроде

EPMD = code:root_dir() ++ "/bin/epmd &",
os:cmd(EPMD),
net_kernel:start([Sname, shortnames])

где Sname - это имя вашего разыскиваемого узла. Только после этого вы можете начать общаться с другим узлом, например, с помощью rpc.

Вы можете анализировать сложные аргументы с помощью escript:

#!/usr/bin/env escript

main(String) ->
  {Node, Mod, Fun, Args} = parse_args(String),
  R = rpc:call(Node, Mod, Fun, Args),
  io:format("~p~n",[R]).
Другие вопросы по тегам