如何用C连续的执行命令并且获得命令的输出?

a359150423 2015-12-01 10:48:27
想写一个C程序,类似于在terminal外面包一层,可以连续的接受我的命令并执行,对于每条命令也可以返回给我相应的结果。
特别是上下文的保持,因为需要执行诸如ssh ,sudo一类的命令。
...全文
266 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
a359150423 2015-12-08
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
仅供参考:
#pragma comment(lib,"user32")
#include <stdio.h>
#include <windows.h>
int main() {
    SECURITY_ATTRIBUTES sa          = {0};
    STARTUPINFO         si          = {0};
    PROCESS_INFORMATION pi          = {0};
    HANDLE              hPipeOutputRead  = NULL;
    HANDLE              hPipeOutputWrite = NULL;
    HANDLE              hPipeInputRead   = NULL;
    HANDLE              hPipeInputWrite  = NULL;
    BOOL                bTest = 0;
    DWORD               dwNumberOfBytesRead = 0;
    DWORD               dwNumberOfBytesWrite = 0;
    CHAR                szMsg[100];
    CHAR                szBuffer[256];

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

    // Create pipe for standard output redirection.
    CreatePipe(&hPipeOutputRead,  // read handle
            &hPipeOutputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Create pipe for standard input redirection.
    CreatePipe(&hPipeInputRead,  // read handle
            &hPipeInputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Make child process use hPipeOutputWrite as standard out,
    // and make sure it does not show on screen.
    si.cb = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput   = hPipeInputRead;
    si.hStdOutput  = hPipeOutputWrite;
    si.hStdError   = hPipeOutputWrite;

    CreateProcess (
          NULL, "cmd.exe",
          NULL, NULL,
          TRUE, 0,
          NULL, NULL,
          &si, &pi);

    // Now that handles have been inherited, close it to be safe.
    // You don't want to read or write to them accidentally.
    CloseHandle(hPipeOutputWrite);
    CloseHandle(hPipeInputRead);

    // Now test to capture DOS application output by reading
    // hPipeOutputRead.  Could also write to DOS application
    // standard input by writing to hPipeInputWrite.
    sprintf(szMsg, "dir *.txt /b\nexit\n");
    WriteFile(
          hPipeInputWrite,      // handle of the write end of our pipe
          &szMsg,               // address of buffer that send data
          18,                   // number of bytes to write
          &dwNumberOfBytesWrite,// address of number of bytes read
          NULL                  // non-overlapped.
          );

    while(TRUE)
    {
       bTest=ReadFile(
          hPipeOutputRead,      // handle of the read end of our pipe
          &szBuffer,            // address of buffer that receives data
          256,                  // number of bytes to read
          &dwNumberOfBytesRead, // address of number of bytes read
          NULL                  // non-overlapped.
          );

      if (!bTest){
          sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
          MessageBox(NULL, szMsg, "WinPipe", MB_OK);
          break;
      }

      // do something with data.
      szBuffer[dwNumberOfBytesRead] = 0;  // null terminate
      MessageBox(NULL, szBuffer, "WinPipe", MB_OK);
    }

    // Wait for CONSPAWN to finish.
    WaitForSingleObject (pi.hProcess, INFINITE);

    // Close all remaining handles
    CloseHandle (pi.hProcess);
    CloseHandle (hPipeOutputRead);
    CloseHandle (hPipeInputWrite);

    return 0;
}
现在有一个基础的思路是在程序创建子进程而后子进程执行bash命令,等待输入。 而后将子进程的输入输出流重定向到父进程的相应文件描述符,以此来达到目的。
赵4老师 2015-12-02
  • 打赏
  • 举报
回复
仅供参考:
#pragma comment(lib,"user32")
#include <stdio.h>
#include <windows.h>
int main() {
    SECURITY_ATTRIBUTES sa          = {0};
    STARTUPINFO         si          = {0};
    PROCESS_INFORMATION pi          = {0};
    HANDLE              hPipeOutputRead  = NULL;
    HANDLE              hPipeOutputWrite = NULL;
    HANDLE              hPipeInputRead   = NULL;
    HANDLE              hPipeInputWrite  = NULL;
    BOOL                bTest = 0;
    DWORD               dwNumberOfBytesRead = 0;
    DWORD               dwNumberOfBytesWrite = 0;
    CHAR                szMsg[100];
    CHAR                szBuffer[256];

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

    // Create pipe for standard output redirection.
    CreatePipe(&hPipeOutputRead,  // read handle
            &hPipeOutputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Create pipe for standard input redirection.
    CreatePipe(&hPipeInputRead,  // read handle
            &hPipeInputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Make child process use hPipeOutputWrite as standard out,
    // and make sure it does not show on screen.
    si.cb = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput   = hPipeInputRead;
    si.hStdOutput  = hPipeOutputWrite;
    si.hStdError   = hPipeOutputWrite;

    CreateProcess (
          NULL, "cmd.exe",
          NULL, NULL,
          TRUE, 0,
          NULL, NULL,
          &si, &pi);

    // Now that handles have been inherited, close it to be safe.
    // You don't want to read or write to them accidentally.
    CloseHandle(hPipeOutputWrite);
    CloseHandle(hPipeInputRead);

    // Now test to capture DOS application output by reading
    // hPipeOutputRead.  Could also write to DOS application
    // standard input by writing to hPipeInputWrite.
    sprintf(szMsg, "dir *.txt /b\nexit\n");
    WriteFile(
          hPipeInputWrite,      // handle of the write end of our pipe
          &szMsg,               // address of buffer that send data
          18,                   // number of bytes to write
          &dwNumberOfBytesWrite,// address of number of bytes read
          NULL                  // non-overlapped.
          );

    while(TRUE)
    {
       bTest=ReadFile(
          hPipeOutputRead,      // handle of the read end of our pipe
          &szBuffer,            // address of buffer that receives data
          256,                  // number of bytes to read
          &dwNumberOfBytesRead, // address of number of bytes read
          NULL                  // non-overlapped.
          );

      if (!bTest){
          sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
          MessageBox(NULL, szMsg, "WinPipe", MB_OK);
          break;
      }

      // do something with data.
      szBuffer[dwNumberOfBytesRead] = 0;  // null terminate
      MessageBox(NULL, szBuffer, "WinPipe", MB_OK);
    }

    // Wait for CONSPAWN to finish.
    WaitForSingleObject (pi.hProcess, INFINITE);

    // Close all remaining handles
    CloseHandle (pi.hProcess);
    CloseHandle (hPipeOutputRead);
    CloseHandle (hPipeInputWrite);

    return 0;
}
corfox_liu 2015-12-01
  • 打赏
  • 举报
回复
用system?
system("ls -l > test.txt");
赵4老师 2015-12-01
  • 打赏
  • 举报
回复
bash是开源的。
qq_29465155 2015-12-01
  • 打赏
  • 举报
回复
动态库链接,每条命令作为一个接口。或者干脆弄个脚本语言调用系统接口函数
zhouxiaofeng1021 2015-12-01
  • 打赏
  • 举报
回复
//用命令行方式检测 BOOL PingIPByCmd(CString& strIP) { DWORD dwStartTicks,dwEndTicks, dwParseTime_ms; dwStartTicks = GetTickCount(); //常量 CString strCmd ; //CString strEnSearch = _T("请求超时"); std::string strChSearch1 = "请求超时"; std::string strChSearch2 = "找不到主机"; strCmd.Format(_T("ping %s"), strIP); BOOL bret; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; //创建管道 HANDLE hReadPipe,hWritePipe; bret = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0); if(!bret) { return FALSE; } //控制命令行窗口信息 STARTUPINFO si; //返回进程信息 PROCESS_INFORMATION pi; si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); si.hStdError = hWritePipe; si.hStdOutput = hWritePipe; si.wShowWindow = SW_HIDE; //隐藏命令行窗口 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; //创建获取命令行进程 bret = CreateProcess(NULL, strCmd.GetBuffer(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ); strCmd.ReleaseBuffer(); if (!bret) { CloseHandle(hWritePipe); return FALSE; } WaitForSingleObject (pi.hProcess, INFINITE); unsigned long count; char szBuffer[512]; //放置命令行输出缓冲区 memset(szBuffer, 0x00, 512); bret = ReadFile(hReadPipe, szBuffer,511, &count, 0); //关闭所有的句柄 CloseHandle(hWritePipe); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(hReadPipe); // 读取失败返回 if(!bret) { return FALSE; } // 分析获取MAC std::string strBuffer = szBuffer; int ipos1 =0, ipos2 =0; ipos1= strBuffer.find(strChSearch1,ipos1); ipos2 = strBuffer.find(strChSearch1,ipos2); dwEndTicks = GetTickCount(); // 计算时长 if (dwEndTicks < dwStartTicks) { dwParseTime_ms = (0xFFFFFFFF - dwStartTicks + dwEndTicks + 1); } else { dwParseTime_ms = (dwEndTicks - dwStartTicks)+1; } dwParseTime_ms= dwParseTime_ms/1000; wcout<<dwParseTime_ms<<endl; if (ipos1>0 && ipos2 >0 ) { return FALSE; } return TRUE; } 不知道我的可以不
a359150423 2015-12-01
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
bash是开源的。
查了一天的terminal,bash,shell有点晕。。。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧