2017-07-10 75 views
1

我試圖使用C程序將stdoutstderr重定向到單個文件。將stdout和stderr都重定向到單個文件並保留消息順序

這裏是我的代碼:

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 

int redirectOutputs(); 

int main() 
{ 
    redirectOutputs(); 
    printf("OUT : test\n"); 
    perror("ERR : test"); 
    printf("OUT : test 2\n"); 


    int t = 23; 
    printf("OUT : again\n"); 
    perror("ERR : again"); 

} 

int redirectOutputs() 
{ 
    int log = open("err.log", O_RDWR|O_CREAT|O_APPEND, 0600); 
    if (log == -1) 
    { 
     perror("opening err.log"); 
     return -1; 
    } 
    close(STDIN_FILENO); 
    close(STDOUT_FILENO); 
    close(STDERR_FILENO); 
    dup2(log, STDOUT_FILENO); 
    dup2(log, STDERR_FILENO); 
    close(log); 
} 

和輸出文件:

ERR : test: Success 
ERR : again: Success 
OUT : test 
OUT : test 2 
OUT : again 

他們都重定向很好,但似乎所有stderr寫,然後所有stdout。 我想保留文件中的消息順序。 我應該有以下文件:

OUT : test 
ERR : test: Success 
OUT : test 2 
OUT : again 
ERR : again: Success 

你知道什麼是我的代碼的問題?

+1

您的輸出是否被緩衝?嘗試調用'fflush()' –

回答

4

的問題是,通過stdout輸出是緩衝stderr無緩衝

您必須使stdout無緩衝像stderr或使stderr緩衝像stdout。您可以使用setvbuf設置緩衝和模式。

你也可以在stdout之後給fflush打電話。

+0

有一個有趣的想法,我目前無法測試。請問'2>&1'做OP的想法? – iehrlich

+1

@iehrlich是的,將shell重定向到'stdout'應該可以正常工作,並且還會消除程序員的一些負擔,因爲不需要編程重定向。 –

+0

感謝您的幫助,那是問題;) – Arkaik

2

您的問題是緩衝。最簡單的解決方案是在每次輸出後調用fflush()。你當然可以明確地設置緩衝到線緩衝setvbuf()


這就是說,它很可能是一個更好的主意,有一個明確的日誌界面,只是選擇性捕獲stderrstdout爲好。最後一句話,你的一些close()調用是多餘的,dup2()在複製之前自動關閉新的fd。

+0

感謝您的幫助,我可能會使用一個日誌宏,寫入標準輸出後會刷新 – Arkaik

相關問題