Есть ли эквивалент Erlang os: cmd, который принимает список строк вместо одной команды? - PullRequest
8 голосов
/ 09 февраля 2010

Есть ли звонок на Эрланге, где я могу сделать Retval = subprocess:call(["cmd", "arg1", "arg2", "arg3"])?

Если я создаю сложную команду для выполнения, с помощью os: cmd / 1 легко избежать ошибок. Сравните с методом Python subprocess.call (), в котором я передаю список строк и знаю, что он передается подпрограмме дословно, ничего не искажено.

Спасибо.

Ответы [ 3 ]

7 голосов
/ 10 февраля 2010

В настоящее время вы можете сделать open_port({spawn_executable, Command}, [{args, [A1, ..., An]}]), но удобной обертки для этого в модуле os пока нет. Вы можете взять код для os:cmd/1 и настроить его для использования spawn_executable. Проверьте документы для erlang:open_port/2 для более подробной информации.

7 голосов
/ 12 февраля 2010

Это то, что я придумал.

-module(mycmd).
-export([cmd/2]).

cmd(Cmd, Args) ->
    Tag = make_ref(), 
    {Pid, Ref} = erlang:spawn_monitor(fun() ->
            Rv = cmd_sync(Cmd, Args),
            exit({Tag, Rv})
        end),
    receive
        {'DOWN', Ref, process, Pid, {Tag, Data}} -> Data;
        {'DOWN', Ref, process, Pid, Reason} -> exit(Reason)
    end.

cmd_sync(Cmd, Args) ->
    P = open_port({spawn_executable, os:find_executable(Cmd)}, [
            binary, use_stdio, stream, eof, {args, Args}]),
    cmd_receive(P, []).

cmd_receive(Port, Acc) ->
    receive
        {Port, {data, Data}} -> cmd_receive(Port, [Data|Acc]);
        {Port, eof}          -> {ok, lists:reverse(Acc)}
    end.
0 голосов
/ 10 февраля 2010

Разве вы не можете просто сделать os:cmd(string:join(["cmd", "arg1", "arg2"], " "))?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...