elixir - How to capture each line from System.cmd output? -


how capture each line written in console when run commands system.cmd or other approach?

i want capture final results displayed in console in case similar to: cloning 'myrepo'... remote: counting objects: 3271, done. , send each line via channels:

case system.cmd("git", ["clone", "git@github.com:#{vault}/#{repo}.git"], cd: repo)   {results, 0} ->     myapp.endpoint.broadcast("app:setup", "new:line", results)   {_, code} ->     raise runtimeerror, "`git clone` failed code #{code}" end 

i haven't found solution, there similar issues without clear answer: question or question

so, there couple approaches here, , i'm going try sum , have able make sense of previous answers in other questions.

first of all, should know handling stuff in detail, need learn how use :erlang.open_port/2. can pass {:line, max_length} options 1 message per line. output git seeing stuff being written stderr, , can pass :stderr_to_stdout redirect come in 1 line per message. can loop using receive until receive eof message, , can see docs more details on when eof message emitted.

bitwalker's answer in second link want modification:

defmodule shell   def exec(exe, args, opts \\ [:stream]) when is_list(args)     port = port.open({:spawn_executable, exe}, opts ++ [{:args, args}, :binary, :exit_status, :hide, :use_stdio, :stderr_to_stdout])     handle_output(port)   end    def handle_output(port)     receive       {^port, {:data, data}} ->         io.inspect(data) # replace appropriate broadcast         handle_output(port)       {^port, {:exit_status, status}} ->         status     end   end end 

now, while can redirect stderr stdout, 1 of problems here git detect redirected stream , adjust how streams accordingly. want compare output of these calls:

gitcmd = system.find_executable("git") shell.exec(gitcmd, ["clone","--progress",url], [{:line, 4096}]) 

this prints out 1 message each "\n" finds in stream. notice junk \r? that's how progress comes out. can remove --progress args, , you'll 1 or 2 boring lines. if want everything, need stream results, , split line-ish output yourself.

shell.exec(gitcmd, ["clone","--progress",url], [:stream]) 

you can see using :stream instead of :line we'll it's being flush'd other side. you'll have clean dangling \r , \n yourself, , may want plan receiving part of line, think should onto journey.

this redirecting stderr stdout, if need retain difference between stderr , stdout, , if want ability kill process, rather depend on closing after close stdin, you're going have rely on porcelain manages well-behaved process "manage" other process you.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -