我通過System.cmd運行在Ubuntu bash命令:System.cmd避免推到日誌
System.cmd("ffmpeg", ["-i", video_path, "-ss", thumbnail_time, "-vframes", "1", "-f", "image2", temp_path])
不幸的是,系統的輸出是如此沉重,所以我不希望看到它,尤其是在我的測試中。我如何使System.cmd
不出現在我的日誌中?
我通過System.cmd運行在Ubuntu bash命令:System.cmd避免推到日誌
System.cmd("ffmpeg", ["-i", video_path, "-ss", thumbnail_time, "-vframes", "1", "-f", "image2", temp_path])
不幸的是,系統的輸出是如此沉重,所以我不希望看到它,尤其是在我的測試中。我如何使System.cmd
不出現在我的日誌中?
在終端中從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中。
要在測試中捕獲(而不是顯示)輸出,請使用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」。
瞭解魔術:
當評估hostfun
的capture_io
替換group_leader
。在Erlang/Elixir ...
每個進程是某個進程組的成員,並且所有組都有一個組長。組中的所有I/O都被傳送給組長。當一個新的過程產生時,它會得到與產卵過程相同的組長。
注意:如果您的ffmpeg的命令寫到stderr
你可以捕捉這一點。
希望這會有所幫助!
'ffmpeg'是否打印stderr?如果是這樣,請嘗試'System.cmd(「ffmpeg」,[「-i」,video_path,「-ss」,thumbnail_time,「-vframes」,「1」,「-f」,「image2」,temp_path],stderr_to_stdout :true)'。 – Dogbert
不,它不會輸入錯誤 – asiniy
您是否在某處打印'System.cmd'的輸出? (你可以試試'stderr_to_stdout:true'嗎?) – Dogbert