溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++如何實(shí)現(xiàn)模擬shell命令行

發(fā)布時(shí)間:2021-12-21 10:43:02 來(lái)源:億速云 閱讀:125 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)C++如何實(shí)現(xiàn)模擬shell命令行的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

一、解析

/**
 * 進(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)前用戶名 */
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)前用戶名 */
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é)果

C++如何實(shí)現(xiàn)模擬shell命令行

感謝各位的閱讀!關(guān)于“C++如何實(shí)現(xiàn)模擬shell命令行”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI