2017-07-10 4 views
1

stdoutstderrの両方をCプログラムの単一のファイルにリダイレクトしようとしています。stdoutとstderrの両方を1つのファイルにリダイレクトしてメッセージの順序を維持する

#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

出力がバッファされていますか?あなたの助けのための ' –

答えて

4

問題はstderrバッファなしであるstdout介して出力をバッファリングされることです。

stderrのようにバッファしないでstdoutにするか、stdoutのようにバッファしたstderrにする必要があります。 setvbufを使用して、バッファリングとモードを設定します。

また、それにそれぞれ出力した後、stdoutfflushを呼び出すことができます。

+0

に足す後にフラッシュされますログのマクロを使用します。 OPが望んでいるので、「2>&1」はトリックになりますか? – iehrlich

+1

@iehrlichはい、シェルが 'stderr'を' stdout'にリダイレクトすることはうまくいくはずですし、プログラムによるリダイレクションが必要ないので、プログラマの負担も軽減します。 –

+0

助けてくれてありがとう、それは問題でした;) – Arkaik

2

あなたの問題はバッファリングです。最も簡単な解決方法は、各出力後にfflush()と呼ぶことです。もちろん、明示的にラインにバッファリングを設定することができsetvbuf()をバッファリング。


言った、おそらく、必要に応じて同様stderrstdoutをキャッチ明示的ログ・インターフェースを持っている良いアイデアだろう。最後に、close()コールのうちのいくつかは冗長です。dup2()は、複製する前に自動的に新しいfdを閉じます。

+0

おかげで)('にfflushを呼び出してみてください、私はおそらく面白いアイデアが、私は現時点でテストすることができませんよということ、ありますSTDOUT – Arkaik

関連する問題