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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With