leo*_*eon 5 elixir phoenix-framework
如何从System.cmd其他方法运行命令时捕获在控制台中写入的每一行?
我甚至想要捕获最终结果,但在这种情况下控制台中显示的内容类似于:Cloning into 'myrepo'... remote: Counting objects: 3271, done.并通过通道发送每一行:
case System.cmd("git", ["clone", "git@github.com:#{vault}/#{repo}.git"], cd: repo) do
{results, 0} ->
Myapp.Endpoint.broadcast("app:setup", "new:line", results)
{_, code} ->
raise RuntimeError, "`git clone` failed with code #{code}"
end
Run Code Online (Sandbox Code Playgroud)
所以,这里有几种方法,我将尝试总结并让您能够理解其他问题中的先前答案.
首先,你应该知道详细处理这些东西,你需要学习如何使用:erlang.open_port/2.您可以传递{:line, max_length}选项以获得每行1条消息.git您看到的输出是写入的内容stderr,您可以传递:stderr_to_stdout重定向,以便每个消息输入1行.您可以循环使用receive直到收到eof消息,并且可以查看文档以获取有关何时eof发出该消息的更多详细信息.
bitwalker在你的第二个链接中的答案将通过一些修改得到你想要的东西:
defmodule Shell do
def exec(exe, args, opts \\ [:stream]) when is_list(args) do
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) do
receive do
{^port, {:data, data}} ->
IO.inspect(data) # Replace this with the appropriate broadcast
handle_output(port)
{^port, {:exit_status, status}} ->
status
end
end
end
Run Code Online (Sandbox Code Playgroud)
现在,虽然我们可以将stderr重定向到stdout,但其中一个问题是git将检测重定向流并调整相应流的流量.我希望你比较这些调用的输出:
gitcmd = System.find_executable("git")
Shell.exec(gitcmd, ["clone","--progress",url], [{:line, 4096}])
Run Code Online (Sandbox Code Playgroud)
这会在流中找到的每个"\n"打印出1条消息.注意所有与\ r \n的垃圾?这就是进步的结果.你可以--progress从args中删除,你只需要获得1或2条无聊线.如果你想获得所有东西,你需要流式传输结果,然后自己分割line-ish输出.
Shell.exec(gitcmd, ["clone","--progress",url], [:stream])
Run Code Online (Sandbox Code Playgroud)
你可以从使用中看到,:stream而不是:line我们会得到所有东西,因为它是从另一方冲洗的.你必须清理悬空\r和\n自己,你可能想要计划接收部分线路,但我认为这应该可以帮助你顺利完成旅程.
这是所有关于重定向错误输出到标准输出,但如果你需要实际保留之间的区别stderr和stdout,如果你想有能力杀死进程,而不是依赖于它关闭你关闭后stdin,你将不得不依赖在像瓷器这样的东西上管理一个表现良好的过程,为你"管理"另一个过程.
| 归档时间: |
|
| 查看次数: |
1427 次 |
| 最近记录: |