如何使用POSIX在C ++中执行命令并获取命令的输出?
我正在寻找一种方法来获取从C ++程序运行时的命令输出。 我已经看过使用system()函数,但那只是执行一个命令。 以下是我正在寻找的一个例子:
std::string result = system( "./some_command" ) ;
我需要运行一个任意的命令并获取它的输出。 我看过Boost.org,但我还没有找到任何能够给我所需的东西。
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
Pre-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 (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}
用Windows的_popen
和_pclose
替换popen
和pclose
。
同时获取stdout和stderr(并写入到标准输入,这里没有显示)很容易与我的pstreams头,它定义了像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';
// read child's stderr
while (std::getline(proc.err(), line))
std::cout << "stderr: " << line << 'n';
}
我会用popen() (++ waqas)。
但有时你需要阅读和写作......
似乎没有人再以艰难的方式做事。
(假设有一个Unix / Linux / Mac环境,或者带有POSIX兼容层的Windows ...)
enum PIPE_FILE_DESCRIPTERS
{
READ_FD = 0,
WRITE_FD = 1
};
enum CONSTANTS
{
BUFFER_SIZE = 100
};
int
main()
{
int parentToChild[2];
int childToParent[2];
pid_t pid;
string dataReadFromChild;
char buffer[ BUFFER_SIZE + 1 ];
ssize_t readResult;
int status;
ASSERT_IS(0, pipe(parentToChild));
ASSERT_IS(0, pipe(childToParent));
switch ( pid = fork() )
{
case -1:
FAIL( "Fork failed" );
exit(-1);
case 0: /* Child */
ASSERT_NOT(-1, dup2( parentToChild[ READ_FD ], STDIN_FILENO ) );
ASSERT_NOT(-1, dup2( childToParent[ WRITE_FD ], STDOUT_FILENO ) );
ASSERT_NOT(-1, dup2( childToParent[ WRITE_FD ], STDERR_FILENO ) );
ASSERT_IS( 0, close( parentToChild [ WRITE_FD ] ) );
ASSERT_IS( 0, close( childToParent [ READ_FD ] ) );
/* file, arg0, arg1, arg2 */
execlp( "ls", "ls", "-al", "--color" );
FAIL( "This line should never be reached!!!" );
exit(-1);
default: /* Parent */
cout << "Child " << pid << " process running..." << endl;
ASSERT_IS( 0, close( parentToChild [ READ_FD ] ) );
ASSERT_IS( 0, close( childToParent [ WRITE_FD ] ) );
while ( true )
{
switch ( readResult = read( childToParent[ READ_FD ],
buffer, BUFFER_SIZE ) )
{
case 0: /* End-of-File, or non-blocking read. */
cout << "End of file reached..." << endl
<< "Data received was ("
<< dataReadFromChild.size() << "):" << endl
<< dataReadFromChild << endl;
ASSERT_IS( pid, waitpid( pid, & status, 0 ) );
cout << endl
<< "Child exit staus is: " << WEXITSTATUS(status) << endl
<< endl;
exit(0);
case -1:
if ( (errno == EINTR) || (errno == EAGAIN) )
{
errno = 0;
break;
}
else
{
FAIL( "read() failed" );
exit(-1);
}
default:
dataReadFromChild . append( buffer, readResult );
break;
}
} /* while ( true ) */
} /* switch ( pid = fork() )*/
}
您也可能想要使用select()和non-blocking读取。
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);
}
链接地址: http://www.djcxy.com/p/12987.html
上一篇: How to execute a command and get output of command within C++ using POSIX?