服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++实现模拟shell命令行(代码解析)

C++实现模拟shell命令行(代码解析)

2022-07-21 09:55Jxiepc C/C++

这篇文章主要介绍了C++实现模拟shell命令行,本文通过实例代码进行命令行解析,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、解析

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * 进行命令行解析:
 * 多个空格
 * 分割符:< > |
 * */
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);    // 获取下一个空格的位置
        tmp = line.substr(i, pos-i);    // 截取字符串
        tmp_vc.push_back(tmp);
        i = pos;
    }
    vc.push_back(tmp_vc);
}

二、执行命令函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/** 执行命令子函数 */
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);
    }
}
 
/** 执行命令
 * --------
 * 创建子进程执行
 * 当出现|需要创建多个子进程
 * 当出现> <则将内容写入文件或者命令行
 * */
void execCommnd(){
    for(int i=0; i<vc.size(); ++i){
        func(vc[i]);
    }
}

三、模拟shell

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/** 获取当前所在目录 */
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 << "]# ";
}
 
/** 获取当前用户名 */
void getIdname(){
    struct  passwd *pwd;
    pwd = getpwuid(getuid());
    std::cout << "["  <<pwd->pw_name << "@";
}
 
/** 获取当前主机名 */
void getHostName(){
    char buf_w[128];
    int hostname = gethostname(buf_w, sizeof(buf_w));
    std::cout << buf_w << " ";
    
}
 
/** 显示菜单 */
void showMenu(){
    getIdname();
    getHostName();
    getCurPwd();
}

四、完整代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*----------------------------------------------------------------------
    > 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>
 
/* 存储命令以及参数 */
std::vector<std::vector<std::string>> vc;
 
/**
 * 进行命令行解析:
 * 多个空格
 * 分割符:< > |
 * */
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);                // 获取下一个空格的位置
        tmp = line.substr(i, pos-i);    // 截取字符串
        tmp_vc.push_back(tmp);
        i = pos;
    }
    vc.push_back(tmp_vc);
}
 
/** 执行命令子函数 */
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);
    }
}
 
/** 执行命令
 * --------
 * 创建子进程执行
 * 当出现|需要创建多个子进程
 * 当出现> <则将内容写入文件或者命令行
 * */
void execCommnd(){
    for(int i=0; i<vc.size(); ++i){
        func(vc[i]);
    }
}
 
/** 获取当前所在目录 */
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 << "]# ";
}
 
/** 获取当前用户名 */
void getIdname(){
    struct  passwd *pwd;
    pwd = getpwuid(getuid());
    std::cout << "["  <<pwd->pw_name << "@";
}
 
/** 获取当前主机名 */
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;
}

四、运行结果

C++实现模拟shell命令行(代码解析)

到此这篇关于C++实现模拟shell命令行的文章就介绍到这了,更多相关C++ shell命令行内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_45926547/article/details/122049266

延伸 · 阅读

精彩推荐