2016-07-16 4 views
0

ich einen Bash-Befehl in Ubuntu über System.cmd ausgeführt wird:System.cmd vermeiden drängen anmeldet

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

Leider ist Systemausgang so schwer, so will ich nicht, um es sehen, vor allem in meinen Tests . Wie kann ich System.cmd nicht in meinen Protokollen erscheinen lassen?

+0

Ist 'ffmpeg' etwas zu stderr drucken? Wenn ja, versuche 'System.cmd (" ffmpeg ", [" -i ", video_path," -ss ", thumbnail_time," -vframes "," 1 "," -f "," image2 ", temp_path], stderr_to_stdout : wahr) '. – Dogbert

+0

Nein, es werden keine Fehler gemacht – asiniy

+0

Drucken Sie die Ausgabe von 'System.cmd' irgendwo? (Könnten Sie 'stderr_to_stdout: true' trotzdem versuchen?) – Dogbert

Antwort

1

Der Grund Sie Ausgabe in Ihrem Terminal aus ffmpeg bekommen, obwohl System.cmd/3 soll die Ausgabe des Befehls zurückzukehren, wie ein binäres dass System.cmd/3 ist standardmäßig nicht stderr Ausgabe nicht erfassen.

Eine Möglichkeit, dies zu beheben, ist es, System.cmd/3 zu fragen, um auch stderr zu erfassen. Sie können das tun, indem stderr_to_stdout: true als drittes Argument übergeben:

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

Ein anderer Weg ist die Protokollebene von ffmpeg zu senken, so dass es nicht so viele Dinge anmeldet, wie es standardmäßig der Fall ist. Sie können dies tun, indem Sie dem Start 2 Parameter hinzufügen: "-loglevel" und einen von "quiet", "panic", oder jede andere Protokollstufe, die Sie wollen. "quiet" sendet absolut keine Ausgabe an stderr, auch wenn der Befehl nicht erfolgreich ausgeführt wird. Diese sind in der ffmpeg's man page dokumentiert.

0

Um Ergebnisse in Tests zu erfassen (und nicht anzuzeigen), verwenden Sie ExUnit.CaptureIO.

Um zu demonstrieren, lassen Sie uns zunächst einen System.cmd ausführen, ohne IO zu erfassen:

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)> 

Sehen Sie, wie der Hostname „dedalus.local“ in die Konsole geschrieben wurde? Das wollen wir vermeiden, oder?

Als nächstes wollen wir den gleichen Befehl ausführen, aber diesmal Erfassung 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)> 

Wir haben die gleichen hostfun laufen, aber diesmal seine System.cmd Ausgabe auf dem Bildschirm geht nicht. Stattdessen wird es erfasst und wir können assert seinen Wert "dedalus.local \ n".

die Magie zu verstehen:
Wenn die Auswertung hostfun die capture_io die group_leader ersetzt. In Erlang/Elixir ...

Jeder Prozess ist ein Mitglied einer Prozessgruppe und alle Gruppen haben einen Gruppenleiter. Alle I/O aus der Gruppe werden zum Gruppenleiter geleitet. Wenn ein neuer Prozess erzeugt wird, erhält er den gleichen Gruppenleiter wie der Laichprozess.

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

Hinweis: Wenn Ihr ffmpeg Befehl stderr schreibt können Sie das auch erfassen.

Hoffe, das hilft!

Verwandte Themen