这篇文章主要介绍了C++实现模拟shell命令行,本文通过实例代码进行命令行解析,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
一、解析
/**
* 进行命令行解析:
* 多个空格
* 分割符:< > |
* */
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]);
}
}
三、模拟shell
/** 获取当前所在目录 */
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();
}
四、完整代码
/*----------------------------------------------------------------------
> 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命令行(代码解析)
基础教程推荐
猜你喜欢
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 设计字符串本地化的最佳方法 2022-01-01