popen function:在C程序中找不到或退出错误状态的命令

时间:2018-04-19 19:04:58

标签: c linux ubuntu-16.04 popen

我正在尝试从ubuntu shell中的C程序执行外部命令,下面是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
    int BUFSIZE = 128;
    char buf[BUFSIZE];
    FILE *fp;

    if ((fp = popen("ls", "r")) == NULL) {
        printf("Error opening pipe!\n");
    }

    while (fgets(buf, BUFSIZE, fp) != NULL) {
        printf("%s", buf);
    }

    if(pclose(fp))  {
        printf("Command not found or exited with error status\n");
    }
    return 1;
}

但它的抛出错误:Command not found or exited with error status,我安装了新的ubuntu 16.04 LTS

1 个答案:

答案 0 :(得分:2)

pclose()将在出错时返回-1。否则,它返回退出状态。如果找不到命令,popen()应该发出某种诊断(但是,它可能没有返回NULL)。

如果pclose()返回退出状态,您应该检查它是否是通过调用wait()返回的。

在评论中,您提到错误是因为您在测试代码中注释了fgets()循环。如果您没有从fp读出数据,则可能会阻止被调用进程尝试向其写入数据。当您调用pclose()时,ls命令可能因SIGPIPE而终止,因为它将尝试写入已关闭的管道。您可以通过检查从pclose()返回的错误状态进行测试。

int status = pclose(fp);

if (status == 0) exit(0);

if (status == -1) {
    perror("pclose");
} else if (WIFSIGNALED(status)) {
    printf("terminating signal: %d", WTERMSIG(status));
} else if (WIFEXITED(status)) {
    printf("exit with status: %d", WEXITSTATUS(status));
} else {
    printf("unexpected: %d", status);
}

如果pclose()确实返回错误,您可以从explain_pclose()获取更详细的错误信息(确保系统上已安装libexplain-dev )。

  

该软件包可能在其他Linux发行版上被命名为libexplain-devel