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\n");
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\n");
return -1;
}

//child
if(pid == 0)
{
//printf("child-----------my process id is %d\n",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\n", 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\n",len);
if (len < 0)
{
if (time(NULL) - btime < nTimeout)
{
usleep(1000);
continue;
}
//printf("[Shell::Execute] parent: kill child pid = %d for timeout %d s\n",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\n",pid);
break;
}
//printf("[Shell::Execute] parent: %s\n",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\n");
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\n");
return -1;
}

//child
if(pid == 0)
{
//printf("child-----------my process id is %d\n",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\n", 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\n",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\n",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\n",pid);
break;
}
//printf("[Shell::Execute] parent: %s\n",buf);
strRet += buf;
}
close(filedes[0]);

return nRe;
}

原文链接: https://www.cnblogs.com/wcc331902579/p/5912892.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    c++实现执行脚本命令

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/241273

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午9:23
下一篇 2023年2月13日 下午9:23

相关推荐