popen函数及输出错误信息

18 篇文章 0 订阅
4 篇文章 0 订阅
#include <cstdio>       // popen, printf, snprintf
#include <sys/wait.h>   // WIFEXITED() WEXITSTATUS()
#include <errno.h>      // extern int errno;
#include <string>
#include <cstring>
#include <cstdlib>
#include <cassert>

#define MAX_SIZE (1024)

bool exec_cmd(const char* command, std::string& errmsg)
{
    assert(command);

    char buffer[MAX_SIZE] = {'\0'};
    std::string final_msg;

    // the exit status of the command.
    int rc = 0; 

    // I/O redirection. 
    char cmd[MAX_SIZE] = {'\0'};
    snprintf(cmd, sizeof(cmd), "%s 2>&1", command);

    FILE *fp = popen(cmd, "r");
    if(NULL == fp)
    {   // if fork(2) or pipe(2) calls fail, or cannot callocate memory.
        // it does not set errno if memory allocation fails.
        // if the underlying fork(2) or pipe(2) fails, errno is set
        // appropriately.
        // if the type arguments is invalid, and this condition is detected,
        // errno is set to EINVAL.
        snprintf(buffer, sizeof(buffer), 
                "popen failed. %s, with errno %d.\n", strerror(errno), errno);
        final_msg = buffer;
        errmsg = final_msg.c_str();
        return false;
    }

    char result[MAX_SIZE] = {'\0'};
    std::string child_result;
    while(fgets(result, sizeof(result), fp) != NULL)
    {
        // remove the '\n' to make output more beautiful
        if('\n' == result[strlen(result)-1])
        {
            result[strlen(result)-1] = '\0';
        }

        snprintf(buffer, sizeof(buffer),
                "[%s]: %s \r\n", command, result);
        child_result += buffer;
    }

    // waits for the associated process to terminate and returns 
    // the exit status of the command as returned by wait4(2).
    rc = pclose(fp);
    if(-1 == rc)
    {   // return -1 if wait4(2) returns an error, or some other error is detected.
        // if pclose cannot obtain the child status, errno is set to ECHILD.
        final_msg += child_result;

        if(ECHILD==errno) {
            final_msg += "pclose cannot obtain the child status.\n";
        }
        else {
            snprintf(buffer, sizeof(buffer),
                    "Close file failed. %s, with errno %d.\n", strerror(errno), errno);
            final_msg += buffer;
        }

        errmsg = final_msg.c_str();
        return false;
    }

    // TODO: warning 'file descriptor leaked
#if 0
    if(WIFEXITED(rc)!=0) {
        printf("maybe cause file descriptor leaked.\n");
    }
#endif

    // child process exit status.
    int status_child = WEXITSTATUS(rc);

    // the success message is here.
    final_msg += child_result;
    snprintf(buffer, sizeof(buffer),
            "[%s]: command exit status [%d] and child process exit status [%d].\r\n",
            command, rc, status_child);
    final_msg += buffer;
    errmsg = final_msg.c_str();

    if(status_child==0) { 
        // child process exits SUCCESS.
        return true;
    }
    else {  
        // child process exits FAILED.
        return false;
    }
}

bool getCmdPath(const char* cmd, String& path)
{
    if (cmd == NULL || strlen(cmd) == 0)
        return false;
    string command = "which ";
    command += cmd;
    FILE* pf = popen(command.c_str(), "r");
    if (pf) {
        char buf[100];
        memset(buf, '\0', sizeof(buf));
        fgets(buf, sizeof(buf), pf);
        pclose(pf);

        //return the path
        path = buf;
        return true;
    } else {
        return false;
    }
}


调用popen函数,执行shell 命令,并输出错误信息。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用popen函数执行外部命令后,可以通过读取文件指针来获取命令的输出结果。具体的读取方式取决于你想要以什么形式获取输出,以下是两种常见的读取方式: 1. 逐行读取输出: ```c FILE *fp; char buffer[256]; fp = popen("command", "r"); // 执行外部命令并获取文件指针 if (fp == NULL) { // 错误处理 } else { while (fgets(buffer, sizeof(buffer), fp) != NULL) { // 处理每一行的输出 printf("%s", buffer); } pclose(fp); // 关闭文件指针 } ``` 在上述示例中,通过调用popen函数执行外部命令并获取文件指针,然后使用fgets函数逐行读取输出到buffer中,可以根据需求对每一行的输出进行处理。 2. 一次性读取全部输出: ```c FILE *fp; char buffer[1024]; size_t bytesRead; fp = popen("command", "r"); // 执行外部命令并获取文件指针 if (fp == NULL) { // 错误处理 } else { bytesRead = fread(buffer, sizeof(char), sizeof(buffer)-1, fp); buffer[bytesRead] = '\0'; // 添加字符串结束符 // 处理输出结果,可以将buffer作为字符串进行操作 printf("%s", buffer); pclose(fp); // 关闭文件指针 } ``` 在上述示例中,通过调用popen函数执行外部命令并获取文件指针,然后使用fread函数一次性读取所有输出到buffer中,可以将buffer作为字符串进行处理。 注意:在使用完popen函数后,需要调用pclose函数关闭文件指针,释放资源。同时,对于较大的输出结果,需要适当调整buffer的大小以避免截断输出

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值