一、解析
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命令行内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/weixin_45926547/article/details/122049266