2014-03-14 140 views
0

我在freebsd下用C開發。我使用cron job來調用一個使用fork()/ exec()調用另一個程序B的程序A.在A中,我使用syslog()將日誌寫入/ var/log/messages,但是B輸出到stdout所以B的輸出不會寫入/ var/log/messages。如何將子進程的輸出重定向到syslog?

如何在不修改B代碼的情況下將B的輸出重定向到syslog?我猜應該有一些機制將B的輸出重定向到A中的某個fd,但由於我使用syslog()而不是直接在A中打開文件,所以我不確定這是如何工作的。

感謝您的建議!

+0

查看'popen',它允許您訪問進程的輸入和輸出文件描述符,也許您可​​以使用代替我們自己的fork/exec。 – Joe

回答

1

我不記得freebsd是否包含記錄器程序。如果是這樣,你的程序A可能會以某種形式的「B |記錄器」來調用B.例如,而不是

execl("/my/path/to/B", "B", NULL); 

槓桿外殼:

execl("/bin/sh", "sh", "-c", "/my/path/to/B | logger", NULL); 

記錄程序有更多的選項指導其消息的特定syslog工具,這可能需要以匹配您的一個應用程序行爲。

缺乏記錄,你可能需要做傳統的Posix管件:使用管(2)創建管道,DUP管道到B的stdout輸出端,並讀取(在A,或在一個單獨的子進程中)管道的消息輸入端發送到syslog(3)

+0

謝謝Sjnarv。我在我的bsd系統中找到了記錄器。但是,我仍然可以得到B的返回碼嗎?無論B返回什麼,我認爲「B | logger」的返回碼將是「記錄器」的返回碼。 –

+0

另外,「cmd」和「sh -c cmd」有什麼區別? –

+0

第一個問題:我認爲你是對的,因爲你不會獲得第一個命令的狀態。作爲替代方案,可能調用'B'需要調用一個名爲B_wrapper.sh的腳本,它是一個調用'B |記錄器「管道,並使用bash陣列PIPESTATUS從第一個命令返回退出狀態。 對於第二個問題:如果「cmd」是一個可執行命令(即文件名),我就知道沒有實際區別。我使用的是包含特定於shell的語法的「cmd」(例如「cmd1 | cmd2」),因此shell可以執行管道連接。 – sjnarv

相關問題