怎么在百度上能搜到自己的网站,网站维护团队,网站内容吸引怎么做才好,wap源码之家上一篇博客学习了重定向#xff0c;所以我们这篇博客将使用我们所学知识对之前写过的myshell进行修改#xff0c;加入重定向操作下面是myshell.cc最开始的代码#include iostream
#include unistd.h
#include cstdio
#include cstdlib
#inclu…上一篇博客学习了重定向所以我们这篇博客将使用我们所学知识对之前写过的myshell进行修改加入重定向操作下面是myshell.cc最开始的代码#include iostream #include unistd.h #include cstdio #include cstdlib #include string #include cstring #include sys/types.h #include sys/wait.h #include unordered_map //shell提示符 #define COMMAND_SIZE 1024 //shell提示符格式(为了区分我们使用#) #define FORMAT [%s%s %s]# //存放命令行参数 #define MAXARGC 128 int g_argc 0; char* g_argv[MAXARGC]; //实现dir更新 #define CWD_SIZE 1024 char cwd[CWD_SIZE]; //记录上一次退出值 int last_exit_code 0; //记录alias映射关系 std::unordered_mapstd::string, std::string alias_list; //实现myshell自己的环境变量 #define MAX_ENVS 100 char* g_env[MAX_ENVS]; int envs 0; //获取用户名 const char* GetUser() { const char* user_name getenv(USER); return user_name NULL ? None : user_name; } //获取shell名 const char* GetHostName() { const char* host_name getenv(HOSTNAME); return host_name NULL ? None : host_name; } //获取pwd const char* GetPwd() { //const char* pwd_name getenv(PWD); const char* pwd_name getcwd(cwd, CWD_SIZE); return pwd_name NULL ? None : pwd_name; } //获取dir std::string GetDir(const char* pwd) { std::string s pwd; if (s /) return /; auto pos s.rfind(/); if (pos std::string::npos) { return BUG?; } return s.substr(pos 1); } //获取home const char* GetHome() { const char* home getenv(HOME); return home NULL ? None : home; } //cd void cd() { if (g_argc 1) { chdir(GetHome()); } else { std::string where g_argv[1]; if (where -) { //需要记录上一个位置这里实现 } else if (where ~) { chdir(GetHome()); } else { chdir(where.c_str()); } } } //echo void echo() { //echo $? //echo $PATH //echo str std::string opt g_argv[1]; if (opt $?) { std::cout last_exit_code std::endl; last_exit_code 0; } else if (opt[0] $) { char* env getenv(opt.substr(1).c_str()); if (env) { std::cout env std::endl; } } else { std::cout opt std::endl; } } //alias void alias() { if (g_argc 2) return; std::string nick_name g_argv[1]; for (int i 2; i g_argc; i) { nick_name std::string(g_argv[i]); } auto pos nick_name.find(); if (pos std::string::npos) return; std::string s1 nick_name.substr(0, pos); std::string s2 nick_name.substr(pos 2, nick_name.size() - 3 - pos); alias_list[s1] s2; } //实现自己的env void InitEnv() { extern char** environ; memset(g_env, 0, sizeof(g_env)); for (int i 0; environ[i]; i) { g_env[i] (char*)malloc(strlen(environ[i]) 1); strcpy(g_env[i], environ[i]); envs; } //测试 g_env[envs] (char*)HELLOMYSHELL; g_env[envs] NULL; for (int i 0; g_env[i]; i) { putenv(g_env[i]); } } //将内容printf到prompt中 void MakeCommandLine(char prompt[], int size) { snprintf(prompt, size, FORMAT, GetUser(), GetHostName(), GetDir(GetPwd()).c_str()); } //打印prompt void PrintCommandPrompt() { char prompt[COMMAND_SIZE]; MakeCommandLine(prompt, COMMAND_SIZE); std::cout prompt; } //获取命令行参数 bool GetCommandLine(char* commandline, int size) { //ls -a -l - ls -a -l\n char* out fgets(commandline, size, stdin); if (out NULL) { return false; } commandline[strlen(commandline) - 1] 0; if (strlen(commandline) 0) //说明只输入了一个回车 { return false; } return true; } //打印命令行参数 void PrintCommandLine(char* commandline) { std::cout commandline std::endl; } //检查是否为重定义命令 void CheckAlias(char* commandline) { char temp[COMMAND_SIZE]; strcpy(temp, commandline); char* cmd strtok(temp, ); if (cmd nullptr || !alias_list.count(cmd)) { return; } char* rest strtok(nullptr, ); std::string new_cmd alias_list[cmd]; if (rest ! nullptr) { new_cmd std::string(rest); } if (new_cmd.size() COMMAND_SIZE) strcpy(commandline, new_cmd.c_str()); } //分割命令行参数 bool CommandParse(char* commandline) { g_argc 0; g_argv[g_argc] strtok(commandline, ); while ((bool)(g_argv[g_argc] strtok(nullptr, ))); g_argc--; return g_argc 0 ? true : false; } //打印分割的命令行参数 void PrintArgv() { for (int i 0; g_argv[i]; i) { std::cout g_argv[i] ; } std::cout std::endl g_argc std::endl; } //判断是否为内建命令 bool CheckAndExecBuiltin() { std::string cmd g_argv[0]; if (cmd cd) { cd(); return true; } else if (cmd echo) { if (g_argc 1) { echo(); return true; } } else if (cmd alias) { alias(); return true; } return false; } //执行命令 int Execute() { pid_t id fork(); if (id 0) { execvp(g_argv[0], g_argv); exit(1); } int status 0; pid_t rid waitpid(id, status, 0); if (rid 0) { last_exit_code WEXITSTATUS(status); } return 0; } int main() { //初始化自己的env InitEnv(); while (true) { //shell提示符 PrintCommandPrompt(); //定义命令行参数 char commandline[COMMAND_SIZE]; //输入命令行参数 if (!GetCommandLine(commandline, COMMAND_SIZE)) { continue; } //判断是否为重定义命令 CheckAlias(commandline); //打印命令行参数 //PrintCommandLine(commandline); //命令行分割(ls -l -a - ls,-l,-a) if (!CommandParse(commandline)) { continue; } //判断内置类型 if(CheckAndExecBuiltin()) { continue; } //打印分割后的命令行参数 //PrintArgv(); //执行命令 Execute(); } return 0; }Makefile代码myshell : myshell.cc g $^ -o $ -stdc11 .PHONY : clean clean : rm myshell开始编写自己的重定向shell#include iostream #include unistd.h #include cstdio #include cstdlib #include string #include cstring #include sys/types.h #include sys/wait.h #include unordered_map #include sys/stat.h #include fcntl.h //shell提示符 #define COMMAND_SIZE 1024 //shell提示符格式(为了区分我们使用#) #define FORMAT [%s%s %s]# //存放命令行参数 #define MAXARGC 128 int g_argc 0; char* g_argv[MAXARGC]; //实现dir更新 #define CWD_SIZE 1024 char cwd[CWD_SIZE]; //记录上一次退出值 int last_exit_code 0; //记录alias映射关系 std::unordered_mapstd::string, std::string alias_list; //实现myshell自己的环境变量 #define MAX_ENVS 100 char* g_env[MAX_ENVS]; int envs 0; //重定向 #define NONE_REDIR 0 #define INPUT_REDIR 1 #define OUTPUT_REDIR 2 #define APPEND_REDIR 3 int redir NONE_REDIR; std::string filename; //获取用户名 const char* GetUser() { const char* user_name getenv(USER); return user_name NULL ? None : user_name; } //获取shell名 const char* GetHostName() { const char* host_name getenv(HOSTNAME); return host_name NULL ? None : host_name; } //获取pwd const char* GetPwd() { //const char* pwd_name getenv(PWD); const char* pwd_name getcwd(cwd, CWD_SIZE); return pwd_name NULL ? None : pwd_name; } //获取dir std::string GetDir(const char* pwd) { std::string s pwd; if (s /) return /; auto pos s.rfind(/); if (pos std::string::npos) { return BUG?; } return s.substr(pos 1); } //获取home const char* GetHome() { const char* home getenv(HOME); return home NULL ? None : home; } //cd void cd() { if (g_argc 1) { chdir(GetHome()); } else { std::string where g_argv[1]; if (where -) { //需要记录上一个位置这里实现 } else if (where ~) { chdir(GetHome()); } else { chdir(where.c_str()); } } } //echo void echo() { //echo $? //echo $PATH //echo str std::string opt g_argv[1]; if (opt $?) { std::cout last_exit_code std::endl; last_exit_code 0; } else if (opt[0] $) { char* env getenv(opt.substr(1).c_str()); if (env) { std::cout env std::endl; } } else { std::cout opt std::endl; } } //alias void alias() { if (g_argc 2) return; std::string nick_name g_argv[1]; for (int i 2; i g_argc; i) { nick_name std::string(g_argv[i]); } auto pos nick_name.find(); if (pos std::string::npos) return; std::string s1 nick_name.substr(0, pos); std::string s2 nick_name.substr(pos 2, nick_name.size() - 3 - pos); alias_list[s1] s2; } //实现自己的env void InitEnv() { extern char** environ; memset(g_env, 0, sizeof(g_env)); for (int i 0; environ[i]; i) { g_env[i] (char*)malloc(strlen(environ[i]) 1); strcpy(g_env[i], environ[i]); envs; } //测试 g_env[envs] (char*)HELLOMYSHELL; g_env[envs] NULL; for (int i 0; g_env[i]; i) { putenv(g_env[i]); } } //将内容printf到prompt中 void MakeCommandLine(char prompt[], int size) { snprintf(prompt, size, FORMAT, GetUser(), GetHostName(), GetDir(GetPwd()).c_str()); } //打印prompt void PrintCommandPrompt() { char prompt[COMMAND_SIZE]; MakeCommandLine(prompt, COMMAND_SIZE); std::cout prompt; } //获取命令行参数 bool GetCommandLine(char* commandline, int size) { //ls -a -l - ls -a -l\n char* out fgets(commandline, size, stdin); if (out NULL) { return false; } commandline[strlen(commandline) - 1] 0; if (strlen(commandline) 0) //说明只输入了一个回车 { return false; } return true; } //打印命令行参数 void PrintCommandLine(char* commandline) { std::cout commandline std::endl; } //找到filename void FilenameFind(char commandline[], int end) { while (commandline[end] ) { end; } } //重定向检查 void RedirCheck(char commandline[]) { redir NONE_REDIR; filename.clear(); int start 0; int end strlen(commandline) - 1; while (start end) { if (commandline[end] ) { commandline[end] \0; FilenameFind(commandline, end); redir INPUT_REDIR; filename commandline end; break; } else if (commandline[end] ) { if (commandline[end - 1] ) { commandline[end - 1] \0; redir APPEND_REDIR; } else { redir OUTPUT_REDIR; } commandline[end] \0; FilenameFind(commandline, end); filename commandline end; break; } else { end--; } } } //检查是否为重定义命令 void CheckAlias(char* commandline) { char temp[COMMAND_SIZE]; strcpy(temp, commandline); char* cmd strtok(temp, ); if (cmd nullptr || !alias_list.count(cmd)) { return; } char* rest strtok(nullptr, ); std::string new_cmd alias_list[cmd]; if (rest ! nullptr) { new_cmd std::string(rest); } if (new_cmd.size() COMMAND_SIZE) strcpy(commandline, new_cmd.c_str()); } //分割命令行参数 bool CommandParse(char* commandline) { g_argc 0; g_argv[g_argc] strtok(commandline, ); while ((bool)(g_argv[g_argc] strtok(nullptr, ))); g_argc--; return g_argc 0 ? true : false; } //打印分割的命令行参数 void PrintArgv() { for (int i 0; g_argv[i]; i) { std::cout g_argv[i] ; } std::cout std::endl g_argc std::endl; } //判断是否为内建命令 bool CheckAndExecBuiltin() { std::string cmd g_argv[0]; if (cmd cd) { cd(); return true; } else if (cmd echo) { if (g_argc 1) { echo(); return true; } } else if (cmd alias) { alias(); return true; } return false; } //执行命令 int Execute() { pid_t id fork(); if (id 0) { int fd -1; if (redir INPUT_REDIR) { fd open(filename.c_str(), O_RDONLY); if (fd 0) { exit(1); } dup2(fd, 0); close(fd); } else if (redir OUTPUT_REDIR) { fd open(filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666); if (fd 0) { exit(1); } dup2(fd, 1); close(fd); } else if (redir APPEND_REDIR) { fd open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0666); if (fd 0) { exit(1); } dup2(fd, 1); close(fd); } execvp(g_argv[0], g_argv); exit(1); } int status 0; pid_t rid waitpid(id, status, 0); if (rid 0) { last_exit_code WEXITSTATUS(status); } return 0; } int main() { //初始化自己的env InitEnv(); while (true) { //shell提示符 PrintCommandPrompt(); //定义命令行参数 char commandline[COMMAND_SIZE]; //输入命令行参数 if (!GetCommandLine(commandline, COMMAND_SIZE)) { continue; } //判断是否为重定向操作ls -a -l xxx.txt - ls -a -l 与 xxx.txt RedirCheck(commandline); //判断是否为重定义命令 CheckAlias(commandline); //打印命令行参数 //PrintCommandLine(commandline); //命令行分割(ls -l -a - ls,-l,-a) if (!CommandParse(commandline)) { continue; } //判断内置类型 if(CheckAndExecBuiltin()) { continue; } //打印分割后的命令行参数 //PrintArgv(); //执行命令 Execute(); } return 0; }本次实现只要看一下我写的代码基本就可以自己实现所以不再过多赘述啦下篇见哦~~