c++实现执行脚本命令

#include "Shell.h"

#include <signal.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

using namespace agent;

Shell::Shell(void)
{
}

Shell::~Shell(void)
{
}

int Shell::Execute(const string& strCmd)
{
if(strCmd.empty())
return -1;

int ret = system(strCmd.c_str());
return ret;
}

int Shell::Execute(const string& strCmd,string& strRet)
{
if(strCmd.empty())
return -1;

#ifdef WIN32
FILE* cmdPipe = _popen(strCmd.c_str(), "rt");
#else
FILE* cmdPipe = popen(strCmd.c_str(), "r");
#endif

if(!cmdPipe)
return -1;

signed char tmpStr(0);
while(true)
{
tmpStr = (char)fgetc(cmdPipe);
if(EOF == tmpStr)
{
break;
}
else
{
strRet += tmpStr;
}
}

#ifdef WIN32
_pclose(cmdPipe);
#else
pclose(cmdPipe);
#endif

return 0;
}

int Shell::Execute(const string& strCmd,string& strRet, const int nTimeout,const string strShell)
{
if(strCmd.empty())
return -1;

//signal(SIGCHLD,SIG_IGN);
string cmd = strShell;
std::string::size_type pos = strShell.find_last_of('/');
if(pos != std::string::npos){
cmd = strShell.substr(pos+1);
}

//create pid
int filedes[2];
if(pipe(filedes) < 0)
{
//printf("[Shell::Execute] pipe create error ");
return -1;
}

//设置为非阻塞
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
//fcntl(filedes[1], F_SETFL, O_NONBLOCK);

int nRe = 0;
pid_t pid = fork();
if(pid < 0)
{
//printf("[Shell::Execute] fork error ");
return -1;
}

//child
if(pid == 0)
{
//printf("child-----------my process id is %d ",getpid());
close(filedes[0]);
if (filedes[1] != STDOUT_FILENO)
{
dup2(filedes[1], STDOUT_FILENO);//复制文件句柄用法
dup2(filedes[1], STDERR_FILENO);
close(filedes[1]);
}

if(cmd == "perl"){
execl(strShell.c_str(), cmd.c_str(), "-e", strCmd.c_str(), (char *)0);
}else{
execl(strShell.c_str(), cmd.c_str(), "-c", strCmd.c_str(), (char *)0);
}
//printf("[Shell::Execute] child: execl: %s ", strerror(errno));//转换错误码为对应的错误信息
_exit(127);
}

//parent
close(filedes[1]);

time_t btime = time(NULL);
char buf[10240 + 1] = {0};
while(true)
{
memset(buf,0,sizeof(buf));
int len = read(filedes[0], buf, sizeof(buf)-1);
//printf("[Shell::Execute] len =================: %d ",len);
if (len < 0)
{
if (time(NULL) - btime < nTimeout)
{
usleep(1000);
continue;
}
//printf("[Shell::Execute] parent: kill child pid = %d for timeout %d s ",pid,nTimeout);
char cmd[100] = {0};
sprintf(cmd,"kill -9 %d",pid);
system(cmd);
len = 0;
nRe = 1;
}

//recv finish or timeout -> break
if(len == 0)
{
if(waitpid(pid, NULL, WNOHANG) == 0)
{
continue;
}
//printf("[Shell::Execute] parent: child pid = %d exit ",pid);
break;
}
//printf("[Shell::Execute] parent: %s ",buf);
strRet += buf;
}
close(filedes[0]);

return nRe;
}


int Shell::ExecuteExit(const string& strCmd,string& strRet, const int nTimeout,bool& bExit,const string strShell)
{
if(strCmd.empty())
return -1;

//signal(SIGCHLD,SIG_IGN);
string cmd = strShell;
std::string::size_type pos = strShell.find_last_of('/');
if(pos != std::string::npos){
cmd = strShell.substr(pos+1);
}

//create pid
int filedes[2];
if(pipe(filedes) < 0)
{
//printf("[Shell::Execute] pipe create error ");
return -1;
}

//设置为非阻塞
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
//fcntl(filedes[1], F_SETFL, O_NONBLOCK);

int nRe = 0;
pid_t pid = fork();
if(pid < 0)
{
//printf("[Shell::Execute] fork error ");
return -1;
}

//child
if(pid == 0)
{
//printf("child-----------my process id is %d ",getpid());
close(filedes[0]);
if (filedes[1] != STDOUT_FILENO)
{
dup2(filedes[1], STDOUT_FILENO);//复制文件句柄用法
dup2(filedes[1], STDERR_FILENO);
close(filedes[1]);
}

if(cmd == "perl"){
execl(strShell.c_str(), cmd.c_str(), "-e", strCmd.c_str(), (char *)0);
}else{
execl(strShell.c_str(), cmd.c_str(), "-c", strCmd.c_str(), (char *)0);
}
//printf("[Shell::Execute] child: execl: %s ", strerror(errno));//转换错误码为对应的错误信息
_exit(127);
}

//parent
close(filedes[1]);

time_t btime = time(NULL);
char buf[10240 + 1] = {0};
while(true)
{
memset(buf,0,sizeof(buf));
int len = read(filedes[0], buf, sizeof(buf)-1);
//printf("[Shell::Execute] len =================: %d ",len);
if (len < 0)
{
if (time(NULL) - btime < nTimeout && !bExit)
{
usleep(1000);
continue;
}
//printf("[Shell::Execute] parent: kill child pid = %d for timeout %d s ",pid,nTimeout);
char cmd[100] = {0};
sprintf(cmd,"kill -9 %d",pid);
system(cmd);
len = 0;
nRe = 1;
}

//recv finish or timeout -> break
if(len == 0)
{
if(waitpid(pid, NULL, WNOHANG) == 0)
{
continue;
}
//printf("[Shell::Execute] parent: child pid = %d exit ",pid);
break;
}
//printf("[Shell::Execute] parent: %s ",buf);
strRet += buf;
}
close(filedes[0]);

return nRe;
}

原文地址:https://www.cnblogs.com/wcc331902579/p/5912892.html