无法使用popen函数读取命令输出

时间:2014-07-02 09:34:12

标签: c linux process popen pid

在Linux中,我通过使用“pidof process_name”命令打开管道然后使用fgets函数读取它的输出来查找进程的pid。但它偶尔找不到pid。下面是我查找我的流程的pid的代码。

int FindPidByProcessName(char *pName)
{
    int pid = -1;
    char line[30] = { 0 };
    char buf[64] = { 0 };

    sprintf(buf, "pidof %s", pName);

    //pipe stream to process
    FILE *cmd = popen(buf, "r");

    if (NULL != cmd)
    {
        //get line from pipe stream
        fgets(line, 30, cmd);
        //close pipe
        pclose(cmd); cmd = NULL;

        //convert string to unsigned LONG integer
        pid = strtoul(line, NULL, 10);
    }

    return pid;
}

在输出中,即使“ps”命令输出中有进程,有时也会出现pid = 0。 所以,我试图找到这个问题背后的根本原因,我发现像输入/输出缓冲机制这样的东西可能会在我的场景中产生问题。

所以我在打开popen()之前尝试使用sync()函数,奇怪的是我的函数开始以100%的准确度工作。

现在,sync()函数花费了太多时间(大约2分钟)来完成执行,这是不可取的。所以我尝试使用fflush(),fsync()和fdatasync(),但这些都没有正常工作。

所以请任何人告诉我这个问题背后的确切根本原因以及如何恰当地解决这个问题?

1 个答案:

答案 0 :(得分:2)

好的,错误的根本原因存储在errno变量中(你不需要初始化)。您可以使用fucntion获取信息性消息

perror("Error: ");

如果您使用perror,则会解释变量errno并获得描述性消息。

查找根本原因的另一种方法(正确方法!)是使用-g标志编译程序并使用gdb运行二进制文件。

编辑:我强烈建议使用gdb调试器,以便您可以准确查看代码所遵循的路径,以便您可以解释您所描述的奇怪行为。

第二次编辑:Errno存储最后一个错误(返回值)。你应该写下来,而不是像你一样调用函数,并立即检查错误:

if ((<function>) <0) {
  perror("<function>: ");
  exit(1);
}