0

コマンドとその引数を使用して呼び出すexecvpと、コマンドが正当でない場合があります。

たとえば、フォークしたSONプロセスを使用してシェル (bash シェル) でこれを行うと、次のようになります。

$ ls ffdfdfd

出力は次のとおりです。

$ ls: cannot access ffdfdfd: No such file or directory

ここで、その正確なメッセージをファイルに渡したいと思います。私はperrorこの方法で試しました:

void directErrors(char * arg)
{
    perror(arg);  // execute the problem to screen

    // now execute the problem to file

    FILE* myFile = fopen("errors.log", "a");

     if(myFile == NULL)
     {
         perror("fopen");
         exit(-1);
     }

     fprintf(myFile, "%s: %s\n", arg, strerror(errno));
     fclose(myFile);
}

ただし、コマンドXが失敗したことを書き込むだけです。

execvp呼び出し後に取得した正確な出力をどのように指示できますか?

私のコードでは、次のexecvpように呼び出します。

executeCurrentCommand = execvp(*(arg)[0], *arg);
4

1 に答える 1

3

プログラムを実行中のプログラムに完全に置き換えるexecことで機能することを忘れないでください。したがって、exec() 呼び出しの後に記述したコードは実行されません。

execvp(cmd, args);
/* This code is never reached.  */

呼び出しが戻る唯一の方法execは、呼び出しようとしているコマンドを実行できない場合です。たとえば、存在しないファイルまたは実行権限のないファイルを実行しようとした場合です。

あなたの場合、コマンド ( ls)存在するため、exec成功します...つまり、実行後のコードは実行されません。このlsコマンドは、いつものように stderr にエラー メッセージを生成します。

の出力をキャプチャしたい場合は、lsもっと工夫する必要があります。たとえば、ログ ファイルに追加するためにファイルを開き、それをdup()stderr ファイル記述子として複製してから、exec 呼び出しを実行できます。新しいプロセスはその設定を継承し、lsstderr に送信されるすべての出力がログに追加されます。stdout と stderr の両方をキャプチャする場合は、両方を複製します。それがシェルなどのやり方です。

ところで、使用*(arg)[0]は私には非常に奇妙に見えます: なぜそれを使用するのですか? より合理的です(*arg)[0](私は思うでしょう)。

于 2012-05-28T20:15:13.640 に答える