Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an Erlang os:cmd equivalent that takes a list of strings instead of a single command?

Tags:

erlang

Is there a Erlang call where I can do Retval = subprocess:call(["cmd", "arg1", "arg2", "arg3"])?

If I'm building a complex command to execute, with os:cmd/1 it is easy to make escaping mistakes. Compare to Python's subprocess.call() method where I pass in a list of strings and know that it is passed verbatim to the subprocess, nothing mangled.

Thanks.

like image 960
me2 Avatar asked Feb 09 '10 17:02

me2


1 Answers

This is what I have come up with.

-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.
like image 158
me2 Avatar answered Sep 20 '22 16:09

me2