10

shellコマンドは$ avrdude -c usbtinyテキストをstderrに出力します。ヘッドレスなどのコマンドでは読めません。もっと多くのcosはstdoutではありません。テキストをstdoutまたはファイルにしたい。どうすればCでそれを行うことができますか?私は最後の質問で問題を解決しようとしましたが、まだ解決していません。

4

4 に答える 4

23

私はOpenBSDでこのようなことを試したことがありませんが、少なくともいくつかの* nixのようなシステムでは、を使用してこれを行うことができますdup2

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

int main(void) {  

  fprintf(stderr, "This goes to stderr\n");

  dup2(1, 2);  //redirects stderr to stdout below this line.

  fprintf(stderr, "This goes to stdout\n");
}
于 2010-06-11T01:56:41.530 に答える
3

通常の方法は次のようになります。

avrdude -c usbtiny 2>&1

これにより、通常はstderrに移動して、代わりにstdoutに移動するように指示されます。ファイルに転送したい場合は、次のようにすることができます。

avrdude -c usbtiny 2> outputfile.txt
于 2010-06-11T01:28:19.220 に答える
0

以下では、POSIX関数を使用して、標準出力ファイル番号を標準エラーファイル番号に複製します。stderrをstdoutに複製するdup2方法は、関数の使用例としてPOSIXページに記載されています。

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

int main (void)
{
    pid_t child = fork();

    if (child == 0)
    {
        dup2(STDOUT_FILENO, STDERR_FILENO);
        execlp("avrdude", "-c", "usbtiny", NULL);
    }
    else if (child > 0)
    {
        waitpid(child);
        puts("Done!");
    }
    else
    {
        puts("Error in forking :(");
    }

    return 0;
}
于 2010-06-11T02:05:40.017 に答える
0

stderrを取得できるように、Cでコマンドをブロックする必要があります

子プロセスを開始する方法についてman fork、を読むことから始めます。を調べて、子供を刈り取る方法を探しman execてください。man 7 signalman sigactionman wait

最後に、man dup2

例示するテストされていないコード:

int pip_stderr[2];
int r;
int pid;

r = pipe(pip_stderr);
assert( r != -1 );

int pid = fork();
assert( pid != -1 );
if (pid == 0) { /* child */
   /* child doesn't need to read from stderr */
   r = close(pip_stderr[0]); assert( r != -1 );
   /* make fd 2 to be the writing end of the pipe */
   r = dup2(pip_stderr[1], 2); assert( r != -1 );
   /* close the now redundant writing end of the pipe */
   r = close(pip_stderr[1]); assert( r != -1 );
   /* fire! */
   exec( /* whatever */ );
   assert( !"exec failed!" );
} else { /* parent */
   /* must: close writing end of the pipe */
   r = close( pip_stderr[1] ); assert( r != -1 );

   /* here read from the pip_stderr[0] */

   r = waitpid(pid,0,0); assert( r == pid );
}

dup2()を使用して、子のstderr(fd 2)をパイプの書き込み端に置き換えます。pipe()はfork()の前に呼び出されます。フォーク後、親プロセスの読み取りが実際にEOFを受け取るように、パイプのすべての吊り下げ端も閉じる必要があります。

おそらくstdioを使用したより簡単な解決策があるでしょうが、私はそれを知りません。popen()はシェルを介してコマンドを実行するため、おそらくstderrをstdoutにリダイレクトするように(そしてstdoutを/ dev / nullに送信するように)指示することができます。それを試したことはありません。

mktemp()(man 3 mktemp)を使用して一時ファイル名を作成し、system()のコマンドを作成してコマンドのstderrを一時ファイルにリダイレクトし、system()が戻った後に一時ファイルを読み取ることもできます。

于 2010-06-11T02:13:57.240 に答える