linux命令由popen在C代码上执行

时间:2013-04-21 01:18:42

标签: c linux popen

我有以下代码,我引用here上的帖子来使用popen函数

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 

上面的代码有什么错误?

3 个答案:

答案 0 :(得分:16)

由于输出是stderr,您需要重定向stderr,如下所示:

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

这会将stderr重定向到stdout,因此您会看到两者的输出。第二个问题fscanf将在第一个空格处停止,因此您可以使用fgets替换:

fgets(buffer, 100, file);

答案 1 :(得分:2)

Shafik Yaghmour正确诊断时,您从ntpdate看到的输出(正确)写入其标准错误,这与您的程序标准错误相同。

要获取从管道发送的错误消息,请使用:

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

ntpdate的标准错误输出发送到命令的标准输出,这是您正在读取的管道。

当然,看起来使用ntpdate在配置某些内容之前效果不佳。

答案 2 :(得分:0)

FILE *popen(const char *command, const char *type);