2016-07-16 76 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你可以捕捉這一點。

希望這會有所幫助!