web-dev-qa-db-ja.com

Cコードでpopenが実行するLinuxコマンド

popen関数を使用するために here のスレッドを参照する以下のコードがあります

int main(int argc,char *argv[]){    
    FILE* file = popen("ntpdate", "r");
    char buffer[100];
    fscanf(file, "%100s", buffer);
    pclose(file);
    printf("buffer is :%s\n", buffer);
    return 0;
}

それは出力します:

21 Apr 03:03:03 ntpdate[4393]: no server can be used, exiting
buffer is:

printfが何も出力しないのはなぜですか? lsをコマンドとして使用すると、printfはls出力を出力します。何が間違ってntpdate実行しているのですか?

以下のコードを実行すると( webpage を参照)

#define COMMAND_LEN 8
#define DATA_SIZE 512

int main(int argc,char *argv[]){


    FILE *pf;
       char command[COMMAND_LEN];
       char data[DATA_SIZE];

       // Execute a process listing
       sprintf(command, "ntpdate");

       // Setup our pipe for reading and execute our command.
       pf = popen(command,"r");

       if(!pf){
         fprintf(stderr, "Could not open pipe for output.\n");
         return;
       }

       // Grab data from process execution
       fgets(data, DATA_SIZE , pf);

       // Print grabbed data to the screen.
       fprintf(stdout, "-%s-\n",data);

       if (pclose(pf) != 0)
           fprintf(stderr," Error: Failed to close command stream \n");

       return 0;
}

私は得る

21 Apr 03:15:45 ntpdate[5334]: no servers can be used, exiting
-�2}�����"|�4#|�-
 Error: Failed to close command stream 

上記のコードの何が問題になっていますか?

8
sven

出力はstderrに送信されるため、次のようにstderrをリダイレクトする必要があります。

FILE* file = popen("ntpdate 2>&1", "r");

これにより、stderrstdoutにリダイレクトされるため、両方からの出力が表示されます。 2番目の問題fscanfは最初のスペースで停止するため、fgetsに置き換えることができます。

fgets(buffer, 100, file);
17
Shafik Yaghmour

Shafik Yaghmour が正しく診断されると、ntpdateからの出力は、プログラムの標準エラーと同じ標準エラーに(正しく)書き込まれます。

パイプを介して送信されるエラーメッセージを取得するには、次のコマンドを使用します。

FILE *file = popen("ntpdate 2>&1", "r");

これにより、ntpdateからの標準エラー出力が、コマンドの標準出力(読み取り元のパイプ)に送信されます。

もちろん、何かを設定するまで、ntpdateを使用してもうまくいかないようです。

2
FILE *popen(const char *command, const char *type);
0
nitai