7

パイプライン経由で ping コマンドの出力をすぐにキャプチャするにはどうすればよいですか?

これが私のコードです:

int main ()
{
    FILE *cmd = popen ( "ping -c 3 google.com | grep icmp", "r" );//ping google
    char *s = malloc ( sizeof ( char ) * 200 );
    while ( 1 )
    {
            fgets ( s, sizeof ( char )*200, cmd );
            printf ( "%s", s);//show outcome
            if ( strstr ( s, "icmp_req=3" ) != 0 )
                    break;
    }
    pclose ( cmd );
    return 0;
}

プログラムが終了すると、同時に出力が表示されます。しかし、プログラムの実行中にすぐに出力を読みたいと思います。

4

5 に答える 5

8

<stdio.h> デフォルトでバッファリングされ、stdoutラインバッファリングされます。

yourprintf("%s", s);printf("%s\n", s);(最後の改行でバッファがフラッシュされます) に置き換えるか、その直後にstdoutへの呼び出しを追加します。fflush(NULL);

実際、あなたの質問は とは関係ありませんpingが、パイプはバッファリングされています。

下位レベルpipeの , fork, dup2syscallsreadを実行して、パイプ上のバッファを明示的に管理することができます。次に、呼び出しpollが役立つ場合があります。

libopingのような ICMP ping ライブラリの使用を検討するか、代わりに HTTP リクエストを行うことを検討できます (wgetプログラムを使用するか、できればlibcurlを使用します。単純な HTTPHEADリクエストで十分かもしれません)。一般的なアドバイスとして、popenorを使用してプロセスを fork することは避けてくださいsystem(使用可能なコマンドがターゲット コンピューターで同じではない可能性があるため)。

http://advancedlinuxprogramming.com/のような優れた Linux プログラミングの本を読んでください。

于 2013-01-22T06:33:04.300 に答える
1

すぐに読み取ることはできず、実行の最後に出力されません。

した瞬間に表示されます。

  • パイプのバッファがいっぱいになった、または

  • パイプが閉じます

パイプのプロパティを変更する必要があります。

于 2013-01-22T06:35:46.900 に答える
1

printf("%s", s);に置き換えますprintf("%s\n", s);

\nバッファをフラッシュするので、printfコマンドが実行されるとすぐに出力が得られ、プログラムの実行が停止するまで待つ必要はありません...

于 2013-01-22T06:38:14.890 に答える
0

改行出力を強制してからstdoutフラッシュし、cmdを次のように変更します

char *cmds = "ping -c 3 google.com | awk ' /icmp/ { printf(\"%s\\n\", $0); } '";
FILE *cmd = popen ( cmds, "r" );

自分でテストして動作します。

問題はパイプのフラッシュに関するものであり、現在のプロセスの stdout フラッシュに関するものではないため、他の方法は機能しません。

于 2013-01-22T09:12:48.143 に答える