• 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;
    }

  • 相关阅读:
    《RocketMQ源码系列》心跳机制
    《RocketMQ源码系列》broker是如何注册到nameserver的
    使用redis客户端工具RedisClient连接windows和linux下的redis并解决无法连接redis的问题
    windows下安装Linux
    redis客户端工具RedisClient的使用
    redis哨兵机制配置
    redis数据的两种持久化方式rdb和aof对比(二)
    redis数据的两种持久化方式rdb和aof对比(一)
    windows下的redis主从复制
    redis持久化配置:rdb和aof
  • 原文地址:https://www.cnblogs.com/wcc331902579/p/5912892.html
Copyright © 2020-2023  润新知