2016-07-16 81 views
0

我通过System.cmd运行在Ubuntu bash命令:System.cmd避免推到日志

System.cmd("ffmpeg", ["-i", video_path, "-ss", thumbnail_time, "-vframes", "1", "-f", "image2", temp_path]) 

不幸的是,系统的输出是如此沉重,所以我不希望看到它,尤其是在我的测试中。我如何使System.cmd不出现在我的日志中?

+0

'ffmpeg'是否打印stderr?如果是这样,请尝试'System.cmd(“ffmpeg”,[“-i”,video_path,“-ss”,thumbnail_time,“-vframes”,“1”,“-f”,“image2”,temp_path],stderr_to_stdout :true)'。 – Dogbert

+0

不,它不会输入错误 – asiniy

+0

您是否在某处打印'System.cmd'的输出? (你可以试试'stderr_to_stdout:true'吗?) – Dogbert

回答

1

在终端中从ffmpeg获得输出的原因,即使System.cmd/3应该将该命令的输出作为二进制返回,默认情况下System.cmd/3不会捕获stderr输出。

解决此问题的一种方法是要求System.cmd/3也捕获stderr。你可以通过传递stderr_to_stdout: true作为第三个参数:

System.cmd("ffmpeg"‌​, ["-i", video_path, "-ss", thumbnail_time, "-vframes", "1", "-f", "image2", temp_path], stderr_to_stdout: true) 

另一种方法是降低ffmpeg日志级别,以便为它在默认情况下它不会记录为很多事情。您可以通过将2个参数添加到开始:"-loglevel""quiet","panic"或您想要的任何其他日志级别之一来完成此操作。即使命令未成功运行,"quiet"也不会向stderr发送任何输出。这些记录在ffmpeg's man page中。

0

要在测试中捕获(而不是显示)输出,请使用ExUnit.CaptureIO

为了演示,让我们先执行System.cmd而不捕获IO:

iex(1)> hostfun = fn -> System.cmd("hostname", [], into: IO.stream(:stdio, :line)) end 
#Function<20.52032458/0 in :erl_eval.expr/5> 
iex(2)> hostfun.() 
dedalus.local 
{%IO.Stream{device: :standard_io, line_or_bytes: :line, raw: false}, 0} 
iex(3)> 

如何看主机名“dedalus.local”被写入到控制台?这就是我们想要避免的,对吧?

接下来,让我们执行相同的命令,但这次拍摄IO:

iex(3)> import ExUnit.Assertions 
ExUnit.Assertions 
iex(4)> import ExUnit.CaptureIO 
ExUnit.CaptureIO 
iex(5)> assert(capture_io(hostfun) == "dedalus.local\n") 
true 
iex(6)> 

我们运行相同hostfun,但这次它System.cmd输出不往屏幕。相反,它被捕获,我们能够assert它的值是“dedalus.local \ n”。

了解魔术:
当评估hostfuncapture_io替换group_leader。在Erlang/Elixir ...

每个进程是某个进程组的成员,并且所有组都有一个组长。组中的所有I/O都被传送给组长。当一个新的过程产生时,它会得到与产卵过程相同的组长。

(从http://erlang.org/doc/man/erlang.html#group_leader-0

注意:如果您的ffmpeg的命令写到stderr你可以捕捉这一点。

希望这会有所帮助!