我想执行一个系统命令(git clone),并通过Phoenix中的通道将输出流式传输给用户?
我能不能让System.cmd流式传输结果,而不是等到结果完成?
或者,我是否可以将输出写到一个文件中,并从那里流式传输内容,因为它是附加的?
发布于 2015-12-09 04:39:19
可以使用以下命令覆盖输出:
System.cmd "git", ["clone", "YOUR_GIT"], into: IO.stream(:stdio, :line)
结果:
克隆到'YOUR_GIT'...远程:计算对象数: 1665,完成。远程:压缩对象: 0% (1/979)远程:压缩对象: 100% (979/979),完成。接收对象: 0% (1/166)远程:总计1665 (增量855),重用1331 (增量597)接收对象: 92% (接收对象: 100% (1665/1665),5.25 MiB | 376.00 KiB/s,完成。解决delResolving增量: 100% (855/855),完成。正在检查连接...好了。
{%IO.Stream{device::standard_io,line_or_bytes::line,raw: false},0}
docs
编辑:
为了帮助您完成特定的任务,将本地标准流重定向到外部流,有一个库porcelain,它是handles it perfectly。
发布于 2015-12-09 16:25:57
我会建议你在这方面使用瓷器。特别要检查https://github.com/alco/porcelain#messages。
您可以使用Porcelain.spawn_shell
运行带有out: {:send, self()}
选项的命令,并实现匹配的handle_info
回调。
发布于 2018-03-02 08:46:49
如果你不想使用瓷器,它有一个go可执行依赖,你可以使用port,如下所示:
def long do
port = Port.open({:spawn_executable, /path/to/command"}, [:stderr_to_stdout, :binary, :exit_status, args: ["arg1"]])
stream_output(port)
end
defp stream_output(port) do
receive do
{^port, {:data, data}} ->
Logger.info(data) # send to phoenix channel
stream_output(port)
{^port, {:exit_status, 0}} ->
Logger.info("Command success")
{^port, {:exit_status, status}} ->
Logger.info("Command error, status #{status}")
end
end
https://stackoverflow.com/questions/34165458
复制相似问题