因此,這裏有幾個方法,我將嘗試總結一下,並且能夠理解其他問題中的以前的答案。
首先,你應該知道,處理這個東西的細節,你需要學習如何使用:erlang.open_port/2
。您可以通過{:line, max_length}
選項每行獲得1條消息。您看到的git
的輸出是正在寫入stderr
的東西,並且您可以通過:stderr_to_stdout
重定向,以便它們每條消息有1行。您可以循環使用receive
,直到您收到eof
消息,並且您可以看到文檔以獲取有關何時發出eof
消息的更多詳細信息。
bitwalker在你的第二個鏈接的答案會得到你想要的東西了一些修改:
defmodule Shell do
def exec(exe, args, opts \\ [:stream]) when is_list(args) do
port = Port.open({:spawn_executable, exe}, opts ++ [{:args, args}, :binary, :exit_status, :hide, :use_stdio, :stderr_to_stdout])
handle_output(port)
end
def handle_output(port) do
receive do
{^port, {:data, data}} ->
IO.inspect(data) # Replace this with the appropriate broadcast
handle_output(port)
{^port, {:exit_status, status}} ->
status
end
end
end
現在,雖然我們可以將stderr重定向到stdout,這裏的一個問題是,git會檢測重定向流並調整相應的流量。我希望您比較這些調用的輸出:
gitcmd = System.find_executable("git")
Shell.exec(gitcmd, ["clone","--progress",url], [{:line, 4096}])
這會在流中找到的每個「\ n」打印出1條消息。注意\ r所有的垃圾?這就是進展情況。你可以從參數中刪除--progress
,你只會得到1或2條無聊的線。如果你想獲得所有東西,你需要流式傳輸結果,然後自行分割輸出。
Shell.exec(gitcmd, ["clone","--progress",url], [:stream])
您可以使用:stream
而不是:line
因爲它是被從另一個側面flush'd我們會得到的一切看到的。您必須自己清理懸掛的\r
和\n
,並且您可能希望計劃接收部分線路,但我認爲這應該可以幫助您順利完成旅程。
這是所有關於重定向錯誤輸出到標準輸出,但如果你需要真正留住stderr
和stdout
之間的區別,如果你想有能力殺死進程,而不是依賴於它關閉關閉stdin
後,你將不得不依賴諸如porcelain之類的東西來管理一個行爲良好的進程,以便爲您「管理」其他進程。