2016-07-26 4 views
0

У меня есть приложение Erlang с именем tb, которое отлично работает из командной строки Erlang, выполняя приложение: start (tb). Если я пытаюсь вызывать одно и то же приложение изнутри escript с помощью os: cmd, приложение, похоже, не запускается. Когда я делаю «ps | grep beam ', я вижу, что процесс beam.smp работает. Но приложение не генерирует никакого вывода. Какая может быть проблема? Есть ли лучший способ запустить еще одну erlang VM изнутри escript?Использование os: cmd в escript для запуска приложения Erlang завершается с ошибкой.

Вот фрагмент кода:

net_kernel:start([tb_escript, shortnames]), 
read_config_file(FName), 
Cookie = get(cookie), 
Node = get(node), 
N = io_lib:format("~p",[Node]), 
lists:flatten(N), 
C = io_lib:format("~p",[Cookie]), 
lists:flatten(C), 
EBIN = "~/tb/ebin", 
erlang:set_cookie(tb_escript,Cookie), 
os:cmd("erl -pa " ++ EBIN ++ " -sname " ++ N ++ " -detached " ++ " -setcookie " ++ C++ " -s application start tb"). 
+0

Можете ли вы попробовать распечатать значение, которое вы передаете 'os: cmd', чтобы посмотреть, выглядит ли оно правильно? Кроме того, 'list: flatten (N)' и 'lists: flatten (C)' ничего не делают, поскольку вы не используете возвращаемое значение. – Dogbert

+0

Dogbert, спасибо за быстрый ответ. Я модифицировал escript для использования выходных списков: flatten(). Однако это, похоже, не устранило проблему. Вот строка, передаваемая в os: cmd "erl -pa ~/tb/ebin -sname timer_bench_node -detached -setcookie rtetimer_dev -s application start tb" И вывод для os: cmd() - пустой список. –

+0

И если вы запустите 'erl -pa ~/tb/ebin -sname timer_bench_node -detached -setcookie rtetimer_dev -s приложение start tb' из командной строки, он отлично работает? – Dogbert

ответ

0

Это происходит потому, что арг флаг -s упаковывает аргументы в список и передает его в module:function/1. -s application start tb выполнит application:start([tb]), который вернет {error,{bad_application,[ssl]}}. Поскольку это только нормальное значение возврата, ошибка не выводится erl.

От erl documentation:

-s Mod [Func [arg1, arg2, ...]] (INIT флаг)

Делает INIT вызвать определенную функцию. Начальные настройки Func. Если аргументы не предусмотрены, предполагается, что функция имеет arity 0. В противном случае предполагается, что она имеет arity 1, в качестве аргумента используется список [Arg1, Arg2, ...]. Все аргументы передаются как атомы.

Есть два способа решить эту проблему:

  1. Использование -eval "application:start(tb)", как вы уже упоминали в комментарии.

  2. Добавить start/0 (если уже не присутствует) функция tb которая вызывает application:start(tb), а затем передать только -s tb в erl. -s с одним аргументом вызовет module:start().