如何在C++;使用POSIX? 我正在寻找一种方法,当它从C++程序运行时,得到命令的输出。我已经研究过如何使用system()函数,但这只会执行一个命令。以下是我正在寻找的一个例子: std::string result = system("./some_command");

如何在C++;使用POSIX? 我正在寻找一种方法,当它从C++程序运行时,得到命令的输出。我已经研究过如何使用system()函数,但这只会执行一个命令。以下是我正在寻找的一个例子: std::string result = system("./some_command");,c++,process,posix,system,return-value,C++,Process,Posix,System,Return Value,我需要运行任意命令并获取其输出。我已经看过了,但没有找到任何能满足我需要的东西。两种可能的方法: L> > P> >我不认为 PONEN()/CUT>是C++标准的一部分(它是POSIX内存的一部分),但它在我使用过的每个UNIX上都是可用的(而且,您的命令似乎是针对UNIX的,因为您的命令是代码> ./某个命令)。 如果没有popen(),您可以使用系统(“/some_command>/tmp/some_command.out”),然后使用常规I/O函数处理输出文件 #包括 #包括 #包括

我需要运行任意命令并获取其输出。我已经看过了,但没有找到任何能满足我需要的东西。

两种可能的方法:

<> L> > P> >我不认为<代码> PONEN()/CUT>是C++标准的一部分(它是POSIX内存的一部分),但它在我使用过的每个UNIX上都是可用的(而且,您的命令似乎是针对UNIX的,因为您的命令是代码> ./某个命令)。
  • 如果没有
    popen()
    ,您可以使用
    系统(“/some_command>/tmp/some_command.out”),然后使用常规I/O函数处理输出文件

  • #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    std::string exec(const char*cmd){
    std::数组缓冲区;
    std::字符串结果;
    标准:独特的ptr管道(popen(cmd,“r”)、pclose);
    如果(!管道){
    抛出std::runtime_错误(“popen()失败!”);
    }
    while(fgets(buffer.data()、buffer.size()、pipe.get())!=nullptr){
    结果+=buffer.data();
    }
    返回结果;
    }
    
    C++11之前的版本:

    #include <iostream>
    #include <stdexcept>
    #include <stdio.h>
    #include <string>
    
    std::string exec(const char* cmd) {
        char buffer[128];
        std::string result = "";
        FILE* pipe = popen(cmd, "r");
        if (!pipe) throw std::runtime_error("popen() failed!");
        try {
            while (fgets(buffer, sizeof buffer, pipe) != NULL) {
                result += buffer;
            }
        } catch (...) {
            pclose(pipe);
            throw;
        }
        pclose(pipe);
        return result;
    }
    
    #包括
    #包括
    #包括
    #包括
    std::string exec(const char*cmd){
    字符缓冲区[128];
    std::string result=“”;
    文件*pipe=popen(cmd,“r”);
    如果(!pipe)抛出std::runtime_错误(“popen()失败!”);
    试一试{
    while(fgets(缓冲区、缓冲区大小、管道)!=NULL){
    结果+=缓冲区;
    }
    }捕获(…){
    pclose(管道);
    投掷;
    }
    pclose(管道);
    返回结果;
    }
    
    将Windows的
    popen
    pclose
    替换为
    \u popen
    \u pclose

    我会使用popen()(++waqas)

    但有时你需要阅读和写作

    似乎再也没有人会这样做了

    (假设是Unix/Linux/Mac环境,或者可能是带有POSIX兼容层的Windows…)


    获取stdout和stderr(以及写入stdin,此处未显示)很容易使用我的头,它定义了类似于
    popen
    的iostream类:

    #include <pstream.h>
    #include <string>
    #include <iostream>
    
    int main()
    {
      // run a process and create a streambuf that reads its stdout and stderr
      redi::ipstream proc("./some_command", redi::pstreams::pstdout | redi::pstreams::pstderr);
      std::string line;
      // read child's stdout
      while (std::getline(proc.out(), line))
        std::cout << "stdout: " << line << '\n';
      # if reading stdout stopped at EOF then reset the state:
      if (proc.eof() && proc.fail())
        proc.clear();
      // read child's stderr
      while (std::getline(proc.err(), line))
        std::cout << "stderr: " << line << '\n';
    } 
    
    #包括
    #包括
    #包括
    int main()
    {
    //运行一个进程并创建一个streambuf来读取其stdout和stderr
    redi::ipstream proc(“./some_命令”,redi::pstreams::pstdout | redi::pstreams::pstderr);
    std::字符串行;
    //阅读儿童读物
    while(std::getline(proc.out(),line))
    
    std::cout以下可能是一个可移植的解决方案。它遵循标准

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdlib>
    #include <sstream>
    
    std::string ssystem (const char *command) {
        char tmpname [L_tmpnam];
        std::tmpnam ( tmpname );
        std::string scommand = command;
        std::string cmd = scommand + " >> " + tmpname;
        std::system(cmd.c_str());
        std::ifstream file(tmpname, std::ios::in | std::ios::binary );
        std::string result;
        if (file) {
            while (!file.eof()) result.push_back(file.get())
                ;
            file.close();
        }
        remove(tmpname);
        return result;
    }
    
    // For Cygwin
    
    int main(int argc, char *argv[])
    {
        std::string bash = "FILETWO=/cygdrive/c/*\nfor f in $FILETWO\ndo\necho \"$f\"\ndone ";
        std::string in;
        std::string s = ssystem(bash.c_str());
        std::istringstream iss(s);
        std::string line;
        while (std::getline(iss, line))
        {
            std::cout << "LINE-> " + line + "  length: " << line.length() << std::endl;
        }
        std::cin >> in;
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    std::string ssystem(const char*命令){
    字符tmpname[L_tmpnam];
    标准:tmpnam(tmpname);
    std::string scommand=command;
    std::string cmd=scommand+“>>”+tmpname;
    std::system(cmd.c_str());
    std::ifstream文件(tmpname,std::ios::in | std::ios::binary);
    std::字符串结果;
    如果(文件){
    而(!file.eof())result.push_back(file.get())
    ;
    file.close();
    }
    删除(tmpname);
    返回结果;
    }
    //给Cygwin
    int main(int argc,char*argv[])
    {
    std::string bash=“FILETWO=/cygdrive/c/*\n对于$FILETWO中的f\ndo\necho\“$f\”\ndone”;
    std::字符串输入;
    std::string s=sssystem(bash.c_str());
    标准:istringstream iss;
    std::字符串行;
    while(std::getline(iss,line))
    {
    
    std::cout对于Windows,
    popen
    也可以工作,但它会打开一个控制台窗口,在您的UI应用程序上快速闪烁。如果您想成为专业人士,最好禁用此“闪烁”(特别是如果最终用户可以取消它)

    下面是我自己的Windows版本:

    (这段代码部分是从中编写的想法和MSDN示例中重新组合而成的。)

    #包括
    #包括
    //
    //执行命令并获得结果。(仅标准输出)
    //
    CStringA ExecCmd(
    要执行的常量wchar\u t*cmd/[in]命令
    )
    {
    CStringA stresult;
    处理hPipeRead、HPIPERWRITE;
    安全属性saAttr={sizeof(安全属性)};
    saAttr.bInheritHandle=TRUE;//管道句柄由子进程继承。
    saAttr.lpSecurityDescriptor=NULL;
    //创建管道以从子对象的标准输出中获取结果。
    如果(!CreatePipe(&hPipeRead,&HPIPERWRITE,&saAttr,0))
    返回strResult;
    STARTUPINFOW si={sizeof(STARTUPINFOW)};
    si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.hStdOutput=hpipebrite;
    si.hStdError=hpipebwrite;
    si.wShowWindow=SW_HIDE;//防止cmd窗口闪烁。
    //需要dwFlags中的STARTF_USESHOWWINDOW。
    进程信息pi={0};
    BOOL fSuccess=CreateProcessW(NULL,(LPWSTR)cmd,NULL,NULL,TRUE,CREATE_NEW_控制台,NULL,NULL,&si,&pi);
    如果(!fsucces)
    {
    CloseHandle(hPipeWrite);
    闭合手柄(hPipeRead);
    返回strResult;
    }
    bool bProcessEnded=false;
    对于(;!bProcessEnded;)
    {
    //给一些时间片(50毫秒),这样我们就不会浪费100%的CPU。
    bProcessEnded=WaitForSingleObject(pi.hProcess,50)=WAIT_OBJECT_0;
    //即使进程退出-我们继续阅读,如果
    //管道上有一些可用的数据。
    对于(;;)
    {
    char-buf[1024];
    DWORD dwRead=0;
    DWORD dwAvail=0;
    if(!::PeekNamedPipe(hPipeRead,NULL,0,NULL,&dwAvail,NULL))
    打破
    如果(!dwAvail)//没有可用数据,则返回
    打破
    if(!::ReadFile(hPipeRead,buf,min(sizeof(buf)-1,dwAvail),&dwRead,NULL)| |!dwRead)
    //错误,子进程可能已结束
    打破
    
    fd_set          readfds;
    struct timeval  timeout;
    
    timeout.tv_sec  = 0;    /* Seconds */
    timeout.tv_usec = 1000; /* Microseconds */
    
    FD_ZERO(&readfds);
    FD_SET(childToParent[READ_FD], &readfds);
    
    switch (select (1 + childToParent[READ_FD], &readfds, (fd_set*)NULL, (fd_set*)NULL, & timeout))
    {
      case 0: /* Timeout expired */
        break;
    
      case -1:
        if ((errno == EINTR) || (errno == EAGAIN))
        {
          errno = 0;
          break;
        }
        else
        {
          FAIL("Select() Failed");
          exit(-1);
        }
    
      case 1:  /* We have input */
        readResult = read(childToParent[READ_FD], buffer, BUFFER_SIZE);
        // However you want to handle it...
        break;
    
      default:
        FAIL("How did we see input on more than one file descriptor?");
        exit(-1);
    }
    
    #include <pstream.h>
    #include <string>
    #include <iostream>
    
    int main()
    {
      // run a process and create a streambuf that reads its stdout and stderr
      redi::ipstream proc("./some_command", redi::pstreams::pstdout | redi::pstreams::pstderr);
      std::string line;
      // read child's stdout
      while (std::getline(proc.out(), line))
        std::cout << "stdout: " << line << '\n';
      # if reading stdout stopped at EOF then reset the state:
      if (proc.eof() && proc.fail())
        proc.clear();
      // read child's stderr
      while (std::getline(proc.err(), line))
        std::cout << "stderr: " << line << '\n';
    } 
    
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdlib>
    #include <sstream>
    
    std::string ssystem (const char *command) {
        char tmpname [L_tmpnam];
        std::tmpnam ( tmpname );
        std::string scommand = command;
        std::string cmd = scommand + " >> " + tmpname;
        std::system(cmd.c_str());
        std::ifstream file(tmpname, std::ios::in | std::ios::binary );
        std::string result;
        if (file) {
            while (!file.eof()) result.push_back(file.get())
                ;
            file.close();
        }
        remove(tmpname);
        return result;
    }
    
    // For Cygwin
    
    int main(int argc, char *argv[])
    {
        std::string bash = "FILETWO=/cygdrive/c/*\nfor f in $FILETWO\ndo\necho \"$f\"\ndone ";
        std::string in;
        std::string s = ssystem(bash.c_str());
        std::istringstream iss(s);
        std::string line;
        while (std::getline(iss, line))
        {
            std::cout << "LINE-> " + line + "  length: " << line.length() << std::endl;
        }
        std::cin >> in;
        return 0;
    }
    
    #include <windows.h>
    #include <atlstr.h>
    //
    // Execute a command and get the results. (Only standard output)
    //
    CStringA ExecCmd(
        const wchar_t* cmd              // [in] command to execute
    )
    {
        CStringA strResult;
        HANDLE hPipeRead, hPipeWrite;
    
        SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES)};
        saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process.
        saAttr.lpSecurityDescriptor = NULL;
    
        // Create a pipe to get results from child's stdout.
        if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0))
            return strResult;
    
        STARTUPINFOW si = {sizeof(STARTUPINFOW)};
        si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        si.hStdOutput  = hPipeWrite;
        si.hStdError   = hPipeWrite;
        si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing.
                                  // Requires STARTF_USESHOWWINDOW in dwFlags.
    
        PROCESS_INFORMATION pi = { 0 };
    
        BOOL fSuccess = CreateProcessW(NULL, (LPWSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        if (! fSuccess)
        {
            CloseHandle(hPipeWrite);
            CloseHandle(hPipeRead);
            return strResult;
        }
    
        bool bProcessEnded = false;
        for (; !bProcessEnded ;)
        {
            // Give some timeslice (50 ms), so we won't waste 100% CPU.
            bProcessEnded = WaitForSingleObject( pi.hProcess, 50) == WAIT_OBJECT_0;
    
            // Even if process exited - we continue reading, if
            // there is some data available over pipe.
            for (;;)
            {
                char buf[1024];
                DWORD dwRead = 0;
                DWORD dwAvail = 0;
    
                if (!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL))
                    break;
    
                if (!dwAvail) // No data available, return
                    break;
    
                if (!::ReadFile(hPipeRead, buf, min(sizeof(buf) - 1, dwAvail), &dwRead, NULL) || !dwRead)
                    // Error, the child process might ended
                    break;
    
                buf[dwRead] = 0;
                strResult += buf;
            }
        } //for
    
        CloseHandle(hPipeWrite);
        CloseHandle(hPipeRead);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return strResult;
    } //ExecCmd
    
    //C++11
    #include <cstdio>
    #include <iostream>
    #include <windows.h>
    #include <cstdint>
    #include <deque>
    #include <string>
    #include <thread>
    
    using namespace std;
    
    int SystemCapture(
        string         CmdLine,    //Command Line
        string         CmdRunDir,  //set to '.' for current directory
        string&        ListStdOut, //Return List of StdOut
        string&        ListStdErr, //Return List of StdErr
        uint32_t&      RetCode)    //Return Exit Code
    {
        int                  Success;
        SECURITY_ATTRIBUTES  security_attributes;
        HANDLE               stdout_rd = INVALID_HANDLE_VALUE;
        HANDLE               stdout_wr = INVALID_HANDLE_VALUE;
        HANDLE               stderr_rd = INVALID_HANDLE_VALUE;
        HANDLE               stderr_wr = INVALID_HANDLE_VALUE;
        PROCESS_INFORMATION  process_info;
        STARTUPINFO          startup_info;
        thread               stdout_thread;
        thread               stderr_thread;
    
        security_attributes.nLength              = sizeof(SECURITY_ATTRIBUTES);
        security_attributes.bInheritHandle       = TRUE;
        security_attributes.lpSecurityDescriptor = nullptr;
    
        if (!CreatePipe(&stdout_rd, &stdout_wr, &security_attributes, 0) ||
                !SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0)) {
            return -1;
        }
    
        if (!CreatePipe(&stderr_rd, &stderr_wr, &security_attributes, 0) ||
                !SetHandleInformation(stderr_rd, HANDLE_FLAG_INHERIT, 0)) {
            if (stdout_rd != INVALID_HANDLE_VALUE) CloseHandle(stdout_rd);
            if (stdout_wr != INVALID_HANDLE_VALUE) CloseHandle(stdout_wr);
            return -2;
        }
    
        ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION));
        ZeroMemory(&startup_info, sizeof(STARTUPINFO));
    
        startup_info.cb         = sizeof(STARTUPINFO);
        startup_info.hStdInput  = 0;
        startup_info.hStdOutput = stdout_wr;
        startup_info.hStdError  = stderr_wr;
    
        if(stdout_rd || stderr_rd)
            startup_info.dwFlags |= STARTF_USESTDHANDLES;
    
        // Make a copy because CreateProcess needs to modify string buffer
        char      CmdLineStr[MAX_PATH];
        strncpy(CmdLineStr, CmdLine.c_str(), MAX_PATH);
        CmdLineStr[MAX_PATH-1] = 0;
    
        Success = CreateProcess(
            nullptr,
            CmdLineStr,
            nullptr,
            nullptr,
            TRUE,
            0,
            nullptr,
            CmdRunDir.c_str(),
            &startup_info,
            &process_info
        );
        CloseHandle(stdout_wr);
        CloseHandle(stderr_wr);
    
        if(!Success) {
            CloseHandle(process_info.hProcess);
            CloseHandle(process_info.hThread);
            CloseHandle(stdout_rd);
            CloseHandle(stderr_rd);
            return -4;
        }
        else {
            CloseHandle(process_info.hThread);
        }
    
        if(stdout_rd) {
            stdout_thread=thread([&]() {
                DWORD  n;
                const size_t bufsize = 1000;
                char         buffer [bufsize];
                for(;;) {
                    n = 0;
                    int Success = ReadFile(
                        stdout_rd,
                        buffer,
                        (DWORD)bufsize,
                        &n,
                        nullptr
                    );
                    printf("STDERR: Success:%d n:%d\n", Success, (int)n);
                    if(!Success || n == 0)
                        break;
                    string s(buffer, n);
                    printf("STDOUT:(%s)\n", s.c_str());
                    ListStdOut += s;
                }
                printf("STDOUT:BREAK!\n");
            });
        }
    
        if(stderr_rd) {
            stderr_thread=thread([&]() {
                DWORD        n;
                const size_t bufsize = 1000;
                char         buffer [bufsize];
                for(;;) {
                    n = 0;
                    int Success = ReadFile(
                        stderr_rd,
                        buffer,
                        (DWORD)bufsize,
                        &n,
                        nullptr
                    );
                    printf("STDERR: Success:%d n:%d\n", Success, (int)n);
                    if(!Success || n == 0)
                        break;
                    string s(buffer, n);
                    printf("STDERR:(%s)\n", s.c_str());
                    ListStdOut += s;
                }
                printf("STDERR:BREAK!\n");
            });
        }
    
        WaitForSingleObject(process_info.hProcess,    INFINITE);
        if(!GetExitCodeProcess(process_info.hProcess, (DWORD*) &RetCode))
            RetCode = -1;
    
        CloseHandle(process_info.hProcess);
    
        if(stdout_thread.joinable())
            stdout_thread.join();
    
        if(stderr_thread.joinable())
            stderr_thread.join();
    
        CloseHandle(stdout_rd);
        CloseHandle(stderr_rd);
    
        return 0;
    }
    
    int main()
    {
        int            rc;
        uint32_t       RetCode;
        string         ListStdOut;
        string         ListStdErr;
    
        cout << "STARTING.\n";
    
        rc = SystemCapture(
            "C:\\Windows\\System32\\ipconfig.exe",    //Command Line
            ".",                                     //CmdRunDir
            ListStdOut,                              //Return List of StdOut
            ListStdErr,                              //Return List of StdErr
            RetCode                                  //Return Exit Code
        );
        if (rc < 0) {
            cout << "ERROR: SystemCapture\n";
        }
    
        cout << "STDOUT:\n";
        cout << ListStdOut;
    
        cout << "STDERR:\n";
        cout << ListStdErr;
    
        cout << "Finished.\n";
    
        cout << "Press Enter to Continue";
        cin.ignore();
    
        return 0;
    }
    
    #include <sys/wait.h>
    #include <unistd.h>
    #include <string>
    #include <vector>
    
    std::string qx(const std::vector<std::string>& args) {
      int stdout_fds[2];
      pipe(stdout_fds);
    
      int stderr_fds[2];
      pipe(stderr_fds);
    
      const pid_t pid = fork();
      if (!pid) {
        close(stdout_fds[0]);
        dup2(stdout_fds[1], 1);
        close(stdout_fds[1]);
    
        close(stderr_fds[0]);
        dup2(stderr_fds[1], 2);
        close(stderr_fds[1]);
    
        std::vector<char*> vc(args.size() + 1, 0);
        for (size_t i = 0; i < args.size(); ++i) {
          vc[i] = const_cast<char*>(args[i].c_str());
        }
    
        execvp(vc[0], &vc[0]);
        exit(0);
      }
    
      close(stdout_fds[1]);
    
      std::string out;
      const int buf_size = 4096;
      char buffer[buf_size];
      do {
        const ssize_t r = read(stdout_fds[0], buffer, buf_size);
        if (r > 0) {
          out.append(buffer, r);
        }
      } while (errno == EAGAIN || errno == EINTR);
    
      close(stdout_fds[0]);
    
      close(stderr_fds[1]);
      close(stderr_fds[0]);
    
      int r, status;
      do {
        r = waitpid(pid, &status, 0);
      } while (r == -1 && errno == EINTR);
    
      return out;
    }
    
    int my_func() {
        char ch;
        FILE *fpipe;
        FILE *copy_fp;
        FILE *tmp;
        char *command = (char *)"/usr/bin/my_script my_arg";
        copy_fp = fopen("/tmp/output_file_path", "w");
        fpipe = (FILE *)popen(command, "r");
        if (fpipe) {
            while ((ch = fgetc(fpipe)) != EOF) {
                fputc(ch, copy_fp);
            }
        }
        else {
            if (copy_fp) {
                fprintf(copy_fp, "Sorry there was an error opening the file");
            }
        }
        pclose(fpipe);
        fclose(copy_fp);
        return 0;
    }
    
    int my_func(){
        char *command = (char *)"/usr/bin/my_script my_arg > /tmp/my_putput_file";
        system(command);
        printf("everything saved in my_output_file");
        return 0;
    }