C++實(shí)現(xiàn)模擬shell命令行(代碼解析)
一、解析
/** * 進(jìn)行命令行解析: * 多個(gè)空格 * 分割符:< > | * */ void parse(){ std::string line; getline(std::cin, line); /** 解析字符串 */ int len = line.size(), i=0; std::string tmp; std::vector<std::string> tmp_vc; while(i < line.size()){ if(line[i] == ' '){ i++; continue; } if(line[i] == '|') { vc.push_back(tmp_vc); tmp = ""; i++; continue; } int pos = line.find(' ', i); // 獲取下一個(gè)空格的位置 tmp = line.substr(i, pos-i); // 截取字符串 tmp_vc.push_back(tmp); i = pos; } vc.push_back(tmp_vc); }
二、執(zhí)行命令函數(shù)
/** 執(zhí)行命令子函數(shù) */ void func(std::vector<std::string>& v){ char *arr[10]; pid_t pid; pid = fork(); if(pid == -1){ std::cout << "fork error" << std::endl; exit(1); }else if(pid ==0){ for(int i=0; i<v.size(); ++i) arr[i] = (char *)v[i].c_str(); arr[v.size()] = NULL; execvp(arr[0], arr); }else{ wait(NULL); } } /** 執(zhí)行命令 * -------- * 創(chuàng)建子進(jìn)程執(zhí)行 * 當(dāng)出現(xiàn)|需要?jiǎng)?chuàng)建多個(gè)子進(jìn)程 * 當(dāng)出現(xiàn)> <則將內(nèi)容寫(xiě)入文件或者命令行 * */ void execCommnd(){ for(int i=0; i<vc.size(); ++i){ func(vc[i]); } }
三、模擬shell
/** 獲取當(dāng)前所在目錄 */ void getCurPwd(){ std::string s = get_current_dir_name(); int pos = s.rfind('/'); std::string tmp = s.substr(pos+1, s.length()-pos); std::cout << tmp << "]# "; } /** 獲取當(dāng)前用戶(hù)名 */ void getIdname(){ struct passwd *pwd; pwd = getpwuid(getuid()); std::cout << "[" <<pwd->pw_name << "@"; } /** 獲取當(dāng)前主機(jī)名 */ void getHostName(){ char buf_w[128]; int hostname = gethostname(buf_w, sizeof(buf_w)); std::cout << buf_w << " "; } /** 顯示菜單 */ void showMenu(){ getIdname(); getHostName(); getCurPwd(); }
四、完整代碼
/*---------------------------------------------------------------------- > File Name: shellDemo.cpp > Author: Jxiepc > Mail: Jxiepc > Created Time: Sun 19 Dec 2021 11:24:21 AM CST ----------------------------------------------------------------------*/ #include <iostream> #include <string> #include <cstring> #include <vector> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <pwd.h> #include <wait.h> /* 存儲(chǔ)命令以及參數(shù) */ std::vector<std::vector<std::string>> vc; /** * 進(jìn)行命令行解析: * 多個(gè)空格 * 分割符:< > | * */ void parse(){ std::string line; getline(std::cin, line); /** 解析字符串 */ int len = line.size(), i=0; std::string tmp; std::vector<std::string> tmp_vc; while(i < line.size()){ if(line[i] == ' '){ i++; continue; } if(line[i] == '|') { vc.push_back(tmp_vc); tmp = ""; i++; continue; } int pos = line.find(' ', i); // 獲取下一個(gè)空格的位置 tmp = line.substr(i, pos-i); // 截取字符串 tmp_vc.push_back(tmp); i = pos; } vc.push_back(tmp_vc); } /** 執(zhí)行命令子函數(shù) */ void func(std::vector<std::string>& v){ char *arr[10]; pid_t pid; pid = fork(); if(pid == -1){ std::cout << "fork error" << std::endl; exit(1); }else if(pid ==0){ for(int i=0; i<v.size(); ++i) arr[i] = (char *)v[i].c_str(); arr[v.size()] = NULL; execvp(arr[0], arr); }else{ wait(NULL); } } /** 執(zhí)行命令 * -------- * 創(chuàng)建子進(jìn)程執(zhí)行 * 當(dāng)出現(xiàn)|需要?jiǎng)?chuàng)建多個(gè)子進(jìn)程 * 當(dāng)出現(xiàn)> <則將內(nèi)容寫(xiě)入文件或者命令行 * */ void execCommnd(){ for(int i=0; i<vc.size(); ++i){ func(vc[i]); } } /** 獲取當(dāng)前所在目錄 */ void getCurPwd(){ std::string s = get_current_dir_name(); int pos = s.rfind('/'); std::string tmp = s.substr(pos+1, s.length()-pos); std::cout << tmp << "]# "; } /** 獲取當(dāng)前用戶(hù)名 */ void getIdname(){ struct passwd *pwd; pwd = getpwuid(getuid()); std::cout << "[" <<pwd->pw_name << "@"; } /** 獲取當(dāng)前主機(jī)名 */ void getHostName(){ char buf_w[128]; int hostname = gethostname(buf_w, sizeof(buf_w)); std::cout << buf_w << " "; } /** 顯示菜單 */ void showMenu(){ getIdname(); getHostName(); getCurPwd(); } void test(){ while(1){ showMenu(); parse(); execCommnd(); } } int main(int argc, char* argv[]) { test(); return 0; }
四、運(yùn)行結(jié)果
到此這篇關(guān)于C++實(shí)現(xiàn)模擬shell命令行的文章就介紹到這了,更多相關(guān)C++ shell命令行內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++類(lèi)成員函數(shù)中的名字查找問(wèn)題
這篇文章主要介紹了C++類(lèi)成員函數(shù)中的名字查找問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C++利用鏈表寫(xiě)一個(gè)簡(jiǎn)單的棧實(shí)例詳解
這篇文章主要介紹了C++利用鏈表寫(xiě)一個(gè)簡(jiǎn)單的棧實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05C++中putchar與getchar函數(shù)的細(xì)節(jié)及運(yùn)用
C語(yǔ)言提供putchar函數(shù),用于給終端輸出一個(gè)字符;getchar函數(shù),可以從終端接收用戶(hù)輸入的一個(gè)字符,本文給大家分享C++中putchar與getchar函數(shù)的細(xì)節(jié)及運(yùn)用,感興趣的朋友跟隨小編一起看看吧2021-07-07在C語(yǔ)言中轉(zhuǎn)換時(shí)間的基本方法介紹
這篇文章主要介紹了在C語(yǔ)言中轉(zhuǎn)換時(shí)間的基本方法,分別是mktime()函數(shù)和localtime()函數(shù)的使用,需要的朋友可以參考下2015-08-08C語(yǔ)言中的內(nèi)聯(lián)函數(shù)(inline)與宏定義(#define)詳細(xì)解析
內(nèi)聯(lián)函數(shù)與宏本質(zhì)上是兩個(gè)不同的概念如果程序編寫(xiě)者對(duì)于既要求快速,又要求可讀的情況下,則應(yīng)該將函數(shù)冠以inline2013-09-09C++11中移動(dòng)構(gòu)造函數(shù)案例代碼
C++11 標(biāo)準(zhǔn)中為了滿(mǎn)足用戶(hù)使用左值初始化同類(lèi)對(duì)象時(shí)也通過(guò)移動(dòng)構(gòu)造函數(shù)完成的需求,新引入了 std::move() 函數(shù),它可以將左值強(qiáng)制轉(zhuǎn)換成對(duì)應(yīng)的右值,由此便可以使用移動(dòng)構(gòu)造函數(shù),對(duì)C++11移動(dòng)構(gòu)造函數(shù)相關(guān)知識(shí)感興趣的朋友一起看看吧2023-01-01Qt實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)單動(dòng)態(tài)時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07C語(yǔ)言菜鳥(niǎo)基礎(chǔ)教程之求1到100的和
在C語(yǔ)言中可以通過(guò)定義一個(gè)累加器(一個(gè)變量)并結(jié)合for循環(huán)來(lái)實(shí)現(xiàn)計(jì)算1到100之和。2017-10-10