你有「手」來複制數據,將其發送到兩個地方,儘管它可以進行與Linux特有的T恤和拼接系統調用會更有效(注意發球系統調用不tee命令, http://blog.superpat.com/2010/07/08/a-cup-of-tee-and-a-splice-of-cake/)
這聽起來像你可能知道如何做到這一點,只是希望不要,但對其他人來說,該解決方案可以是這樣的:
DUP2原來的標準錯誤(通常是終端)向新文件描述符來保存它。然後用管道()製作一個管道。 dup2將管道的寫入結束寫入fd 2.關閉原始寫入結束fd。現在你的stderr是一個管道。啓動線程或進程。在此線程中,將管道讀取端的數據複製到您保存的文件和原始stderr中。當線程或進程通過EOF讀取管道時,關閉它並退出。
popen(「tee」)解決方案是相同的,只不過它創建了一個額外的shell進程(並且您必須正確引用傳遞給shell的文件名,以防其中存在特殊字符時......請務必使用大於符號,空格和引號標記來測試奇怪的文件名......)。如果使用popen,我認爲你也可能有一個(化妝品?)問題,你不能pclose(),因爲你的stderr將停止工作,所以你將永遠留下一個額外的fd打開,並不會等待孩子。
如果你使用的是像GLib這樣的東西,它有一個g_spawn_async函數系列,可以用來在沒有shell的情況下產生tee命令。否則,你將不得不手動執行fork/exec的東西來避免shell;你可以執行tee命令,或者你可以fork但不是exec - 只需在fork完成stderr複製之後有子代碼,不要依賴tee命令。或者,您可以使用線程而不是進程。
如果使用fork,可以在gspawn.c中找到源代碼有用;在任何複雜的程序中,例如FD_CLOEXEC並不是Unix上的默認值,這很容易讓孩子繼承造成問題的描述符。 避免殭屍進程並處理所有錯誤和等等也是很煩人的。
無論如何,是的,它是比預期更多的代碼,但是在coreutils和gspawn.c的tee源碼之間,你可能有大部分可用於複製。
您可以嘗試「尾巴」在屏幕上查看您的輸出文件。這是最簡單的解決方案。 –
@OrcunC我怎麼知道有多少行尾? – PALEN
你不必知道行數。它總是顯示最後n個行數。如果你正在尋找一個特定的模式,你可以很容易地結合尾部和grep以及一個強大的日誌查看器。 –