C/C++编程:执行终端命令

1059 篇文章 285 订阅

linux

#include <cstdlib>
int main(int argc, char **argv)
{
    system("ls -al /etc/passwd /etc/shadow");
    return 0;
}

#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;


int main(){
    char line[300];
    FILE *fp;
    string cmd = "ping www.baidu.com";
    int count = 0;
    // system call
    const char *sysCommand = cmd.data();
    if ((fp = popen(sysCommand, "r")) == NULL) {
        cout << "error" << endl;
        return 0;
    }


    while (fgets(line, sizeof(line)-1, fp) != NULL){
        cout << "count ---> " << count << "   line ---> " <<line    << endl;
        count++;
        if(count == 20){
            break;
        }
    }
    pclose(fp);
    return 0;
}
#include <cstdlib>
int main(int argc, char **argv)
{
    std::system("ls -l");
    return 0;
}


获取命令返回结果:

std::string getCmdResult(const std::string &strCmd)
{
    char buf[10240] = {0};
    FILE *pf = NULL;

    if( (pf = popen(strCmd.c_str(), "r")) == NULL )
    {
        return "";
    }

    std::string strResult;
    while(fgets(buf, sizeof buf, pf))
    {
        strResult += buf;
    }

    pclose(pf);

    unsigned int iSize =  strResult.size();
    if(iSize > 0 && strResult[iSize - 1] == '\n')  // linux
    {
        strResult = strResult.substr(0, iSize - 1);
    }

    return strResult;
}

windows

#include <iostream>
#include <string>
#include <Windows.h>

using namespace std;

/*
获取CMD执行结果
cmdLine:要执行的命令
*/
char* GetCmdRet(char* cmdLine);

int main(void)
{
    char* ret = GetCmdRet("echo y | pscp.exe -pw 123xhy C:/Users/oceanstar/source/QT/deployment_gui_release.zip  root@192.168.0.24:/home/oceanstar/workspace/");
    cout << ret << endl;
    free(ret);
    cout << "\n====================------====================\n" << endl;
    /*ret = GetCmdRet("dir");
    cout << "----" << ret << endl;
    free(ret);

    cout << "\n====================------====================\n" << endl;
    ret = GetCmdRet("ipconfig");
    cout << ret << endl;
    free(ret);
    */
    system("pause");
    return 0;
}

char* GetCmdRet(char* cmdLine)
{
    HANDLE hRead = NULL, hWrite = NULL;
    PROCESS_INFORMATION pInfo = { 0 };
    SECURITY_ATTRIBUTES se = { 0 };
    STARTUPINFO sInfo = { 0 };
    char tmpCmd[1000000] = { 0 }, * retStr = NULL;
    DWORD dwLen = 0;
    string ret;

    se.nLength = sizeof(se);
    se.lpSecurityDescriptor = NULL;
    se.bInheritHandle = TRUE;

    // 创建一个匿名管道
    CreatePipe(&hRead, &hWrite, &se, 0);

    sInfo.cb = sizeof(sInfo);
    sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 这两个常量分别用于设置隐藏窗口+输出目标
    sInfo.wShowWindow = SW_HIDE; // 隐藏窗口运行
    sInfo.hStdOutput = hWrite;    // 让其输出到这个管道去而不是输出到控制台
    sInfo.hStdError = hWrite;    // 错误信息也是输出到该管道
    sprintf_s(tmpCmd, MAX_PATH, "cmd.exe /c %s", cmdLine);
    CreateProcess(NULL, tmpCmd, NULL, NULL, TRUE, NULL, NULL, NULL, &sInfo, &pInfo);
    CloseHandle(hWrite);

    while (dwLen != -1)
    {
        // 查看管道中是否有数据
        PeekNamedPipe(hRead, NULL, NULL, NULL, &dwLen, NULL);
        if (dwLen)
        {
            memset(tmpCmd, 0, MAX_PATH);
            // 读取管道数据
            ReadFile(hRead, tmpCmd, dwLen, &dwLen, NULL);
            ret += tmpCmd;
            cout <<"---------------" <<tmpCmd << endl;
        }
        else
        {
            DWORD dwExit = 0;
            GetExitCodeProcess(pInfo.hProcess, &dwExit);
            // 避免程序已经退出,但管道仍有数据的情况
            if (dwExit != STILL_ACTIVE)
            {
                CloseHandle(hRead);
                break;
            }
        }
        // 一定要加个延时,否则可能有重复数据
        Sleep(1);
    }
    retStr = (char*)malloc(sizeof(char) * ret.length() + 1);
    memset(retStr, 0, ret.length() + 1);
    strncpy(retStr, ret.c_str(), ret.length() + 1);
    return retStr;
}

#include <iostream>
#include <string>

#include <QDebug>

#include <QCoreApplication>
#include <QProcess>
#include <windows.h>


BOOL ExecDosCmd(char* cmdLine)
{
#define EXECDOSCMD   "dir"
  //"ping http://www.baidu.com" //可以换成你的命令

    HANDLE hRead = NULL, hWrite = NULL;
    SECURITY_ATTRIBUTES se;
    se.nLength = sizeof(SECURITY_ATTRIBUTES);
    se.lpSecurityDescriptor = NULL;
    se.bInheritHandle = TRUE;

    if (!CreatePipe(&hRead,&hWrite,&se,0))
    {
        std::cout <<"CreatePipe failed"  << std::endl;
        return FALSE;
    }

    char tmpCmd[1000000] = { 0 };
    sprintf_s(tmpCmd, MAX_PATH, "cmd.exe /c %s", cmdLine);
    QString str(tmpCmd);

    STARTUPINFO sInfo = { 0 };
    sInfo.cb = sizeof(sInfo);
    sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 这两个常量分别用于设置隐藏窗口+输出目标
    sInfo.wShowWindow = SW_HIDE; // 隐藏窗口运行
    sInfo.hStdOutput = hWrite;    // 让其输出到这个管道去而不是输出到控制台
    sInfo.hStdError = hWrite;    // 错误信息也是输出到该管道

    PROCESS_INFORMATION pInfo = { 0 };

    if (!CreateProcess(NULL, (LPWSTR)str.utf16(),NULL,NULL,TRUE,NULL,NULL,NULL, &sInfo, &pInfo))
    {
        std::cout <<"CreateProcess failed " <<tmpCmd << std::endl;
        CloseHandle(hWrite);
        CloseHandle(hRead);
        return FALSE;
    }
    CloseHandle(hWrite);


    std::string ret;
    DWORD dwLen = 0;
    char * retStr = NULL;
    while (dwLen != (DWORD)-1)
    {
        // 查看管道中是否有数据
        PeekNamedPipe(hRead, NULL, NULL, NULL, &dwLen, NULL);
        if (dwLen)
        {
            memset(tmpCmd, 0, MAX_PATH);
            // 读取管道数据
            ReadFile(hRead, tmpCmd, dwLen, &dwLen, NULL);
            ret += tmpCmd;
            std::cout <<"---------------" <<tmpCmd << std::endl;
        }
        else
        {
            DWORD dwExit = 0;
            GetExitCodeProcess(pInfo.hProcess, &dwExit);
            // 避免程序已经退出,但管道仍有数据的情况
            if (dwExit != STILL_ACTIVE)
            {
                CloseHandle(hRead);
                break;
            }
        }
        // 一定要加个延时,否则可能有重复数据
        Sleep(1);
    }
    CloseHandle(hRead);
    return TRUE;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    ExecDosCmd("ping www.baidu.com");

    return a.exec();
}

参考

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值