shahryarjb
How to send line by line of System.cmd to LiveView when a task is running
Hi friend,
I run 3 or 4 different command with System.cmd, so users wait for these tasks are done and after getting status 0 can do another jobs, but I need a way to show them System.cmd log line by line when is running not show all the log at the end.
System.cmd(operation, [command], into: IO.stream(), stderr_to_stdout: true, env: [{"MIX_ENV", "#{Mix.env()}"}])
And if this feature is available at any time, it will be very attractive. For example, from the middle of the log, if requested, show not the whole log or sending any line to PubSub to the channel.
Thank you
Marked As Solved
Also Liked
ruslandoga
You might be able to do that with Port.open and then receive messages coming from it and send them to the liveview process.
port.exs
defmodule Command do
def exec(cmd, args) do
path = System.find_executable(cmd)
port = Port.open({:spawn_executable, path}, [:binary, :exit_status, args: args, line: 1000])
loop(port)
end
defp loop(port) do
receive do
{^port, {:data, data}} ->
IO.inspect(data: data)
loop(port)
{^port, {:exit_status, exit_status}} ->
IO.inspect(exit_status: exit_status)
end
end
end
Command.exec("cat", ["port.exs"])
> elixir port.exs
[data: {:eol, "defmodule Command do"}]
[data: {:eol, " def exec(cmd, args) do"}]
[data: {:eol, " path = System.find_executable(cmd)"}]
[
data: {:eol,
" port = Port.open({:spawn_executable, path}, [:binary, :exit_status, args: args, line: 1000])"}
]
[data: {:eol, " loop(port)"}]
[data: {:eol, " end"}]
[data: {:eol, ""}]
[data: {:eol, " defp loop(port) do"}]
[data: {:eol, " receive do"}]
[data: {:eol, " {^port, {:data, data}} ->"}]
[data: {:eol, " IO.inspect(data: data)"}]
[data: {:eol, " loop(port)"}]
[data: {:eol, ""}]
[data: {:eol, " {^port, {:exit_status, exit_status}} ->"}]
[data: {:eol, " IO.inspect(exit_status: exit_status)"}]
[data: {:eol, " end"}]
[data: {:eol, " end"}]
[data: {:eol, "end"}]
[data: {:eol, ""}]
[data: {:eol, "Command.exec(\"cat\", [\"port.exs\"])"}]
[exit_status: 0]
ruslandoga
axelson
I’d recommend looking into exexec | Hex (which wraps the erlexec Erlang library) especially if the command you want to run are not written to conform to the behavior that Port expects.
Last Post!
shahryarjb
Thank you for all your efforts, it works, and I need to make it comfortable with my code and idea in my project; but I think I got my needed answer, so I need to do more research and work with it.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









