C 學習 通過管道進行cmd程序輸入輸出重定向

2021-06-08 20:44:56 字數 3015 閱讀 1085

在日常的工作中,shell使用比較多,尤其在軟體測試過程中,但使用手工操作既麻煩,又記不住命令,關鍵是不能自動化。眾所周知,linux或者windows系統的shell都是可以進行輸入輸出重定向的,利用輸入輸出重定向技術,把shell的輸入輸出對映到自己所寫的程序裡,這樣就很方面了。比如要使用ssh2遠端乙個linux機器,就需要自己實現ssh2客戶端的協議,使用重定向,就可以直接使用作業系統自帶的ssh(linux系統),或者putty(windows下的telnet、ssh命令)。

本文所要講述的實現方法就是利用管道,管道的概念,大家網上搜尋,這裡還是通過直接show**的方式進行講述,另外進行了簡單的封裝和進一步的抽象,大家可以直接使用,擴充套件起來也比較方便。本文是基於win32,linux實現留給大家自己當著作業吧,於此類似。

首先設計shell型別的大概的樣子如下:

#include "windows.h"

class shell

;

上述**,重定向的控制代碼儲存起來,目的是方便使用者自己擴充套件,同時也儲存了cmd程序的資訊,可以在程式推出的時候,殺掉cmd程序。接下來看看建構函式和析構函式,資源初始化和釋放。

shell::shell(void)

shell::~shell(void)

接下來就是建立程序(比如cmd.exe)了,便於進行輸入輸出操作,**如下:

bool shell::runprocess( const string &process )

//建立子程序輸入匿名管道

if( false == createpipe(&m_hchildinputread, &m_hchildinputwrite, &sa, 0) )

zeromemory(&m_cmdpi, sizeof(m_cmdpi));

startupinfo si;

getstartupinfo(&si);

si.cb = sizeof(startupinfo);

si.dwflags = startf_usestdhandles|startf_useshowwindow;

si.wshowwindow = sw_hide;

si.hstdinput = m_hchildinputread; //重定向子程序輸入

si.hstdoutput = m_hchildoutputwrite; //重定向子程序輸入

si.hstderror = m_hchildoutputwrite;

if( false == ::createprocess(null, (process.c_str()), null, null, true, normal_priority_class, null, null, &si, &m_cmdpi) )

return true;

}

bool shell::stopprocess( void )

如果你想通過putty來實現telnet、ssh操作進行,一是把cmd.exe替換為putty命令列的形式,另外一種形式,就是把putty當著普通的shell命令執行即可。程序建立好了,下面來看看讀寫函式的實現:

bool console::getoutput( const string &endstr, int timeout, string &outstr )

outstr = "";

char buffer[4096] = ;

dword readbytes = 0;

while( timeout > 0 )

//檢測是否讀到資料,如果沒有資料,繼續等待

if( 0 == readbytes )

readbytes = 0;

if( ::readfile( m_hchildoutputread, buffer, sizeof(buffer) - 1, &readbytes, null) )

if( pos == outstr.size() - endstr.size() )

}else

}return false;

}bool shell::setinput( const string &cmd )

string tmp = cmd + "\r\n";

dword writebytes = 0;

if( false == ::writefile( m_hchildinputwrite, tmp.c_str(), tmp.size(), &writebytes, null ) )

return true;

}

寫函式實在是平淡無奇,就是呼叫writefile,只要把控制代碼傳遞對了就行,這幾個控制代碼是容易混淆,大家仔細閱讀**,仔細理解。在讀函式中,使用了peeknamedpipe函式,對管道進行資料讀,這個函式有個作用,即使管道中沒有資料,但會立即返回,不會讀阻塞。這個時候再呼叫readfile就不會阻塞了。同時,使用sleep函式就能簡單的實現超時讀的功能。這個是readfile辦不到的。

到此為止,**已經實現完了,很簡單吧,曾經為了實現ssh2客戶端,費盡心思,找了無數個開源**研究。用這個方法來實現,真是太簡單了。不是嗎?下面來看看測試**:

大功告成,**實現沒有用到什麼高階技巧,但簡單適用,大家不妨直接借用,也許能幫助大家解決日常的工作問題。

C 學習 輸入輸出

程式的輸入指的是從輸入檔案將資料傳送給程式,程式的輸出指的是將資料傳送給輸出檔案 標準i o 鍵盤輸入,輸出到顯示器螢幕 檔案i o 磁碟檔案輸入,輸出到磁碟檔案 串i o 字元陣列作為儲存空間 實際上可以利用該控制項儲存任何資訊 char c cin.get 一次只能輸入乙個字元 cout c c...

C 學習 輸入輸出

標準型別的資料可以通過對cout物件執行流插入運算 來實現。流插入運算是乙個二元運算子。對於cout 123,它的第乙個運算物件是輸出流物件cout,第二個運算物件乙個二元運算子。有插入入運算的返回值為第乙個引數的引用。所以劉插入運算允許連續使用。如cout 字元型資料還可以用成員函式put來輸出。...

C語言學習009 管道連線輸入輸出

現在我們需要對gpsdata.csv檔案中的資料進行篩選,然後將符合條件的資料輸出到output.json檔案中,第一種方式當然是在之前的 中進行修改,但是如果我們不想修改原來的 就能得到我們期望的結果,該如何實現呢?42.0908,71.2316,speed 21 37.1908,74.2322,...