操作系统课设之简单 shell 命令行解释器的设计与实现
前言
課程設計開始了,實驗很有意思,寫博客總結學到的知識
白嫖容易,創作不易,學到東西才是真
本文原創,創作不易,轉載請注明!!!
本文鏈接
個人博客:https://ronglin.fun/archives/185
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/118310091
為了美觀,實驗源代碼在結尾處,整合版見下
鏈接:https://pan.baidu.com/s/1rXj1QJGuw-BVc5sQWret9w
提取碼:Lin2
操作系統課程設計源代碼
本次操作系統課程設計合集
操作系統課設之Windows 進程管理
操作系統課設之Linux 進程管理
操作系統課設之Linux 進程間通信
操作系統課設之Windows 的互斥與同步
操作系統課設之內存管理
操作系統課設之虛擬內存頁面置換算法的模擬與實現
操作系統課設之基于信號量機制的并發程序設計
操作系統課設之簡單 shell 命令行解釋器的設計與實現
僅用于學習,如有侵權,請聯系我刪除
實驗題目
簡單 shell 命令行解釋器的設計與實現
實驗目的
本實驗主要目的在于進一步學會如何在 Linux 系統下使用進程相關的系統調用,了解 shell 工作的基本原理,自己動手為 Linux 操作系統設計一個簡單的命令接口。
總體設計(含背景知識或基本原理與算法、或模塊介紹、設計步驟等)
背景知識:
本實驗要使用創建子進程的 fork()函數,執行新的命令的 exec()系列函數,通常 shell 是等待子進程結束后再接受用戶新的輸入,這可以使用 waitpid()函數。以上相關的系統函數調用的說明請參見實驗二的背景知識。
需求分析:
題目要求設計的 shell 是類似于 sh,bash,csh 等,必須支持以下內部命令:
cd <目錄> 能輸出PWD,更改工作目錄
environ 列出所有環境變量字符串的設置,類似env 命令。
echo <內容> 顯示 echo 后的內容且換行
help 提供對于本shell的幫助
jobs 輸出 shell 當前的一系列子進程,必須提供子進程的命名和 PID 號。
quit,exit,bye 退出 shell。
總體設計:
我將輸入的指令分成三類,第一類是錯誤指令,表示本shell沒添加的shell;第二類是內部指令,就是需求中提到的指令,第三類是shell中自定義的指令,我設計的是如果輸入的指令中含有”lin”就輸出”linxx,希望你開心每一天”.
同時對于內部指令還分為兩類,一類是需要子進程調用exec()的命令,有:“cd”,“environ”,“jobs”,其他都是不需要子進程的,直接按照輸入處理就行了。
詳細設計(含主要的數據結構、程序流程圖、關鍵代碼等)
因為涉及到大量的字符串操作,本次在Linux下用c++實現,主要是用到string類型的方法。
第一部分 輸入
因為輸入需要將空格也輸入進去,所以這里特意提一下
string cmd; cout<<"請輸入指令: "; getline(cin,cmd);第二部分 識別指令
這部分用的是string自帶的方法find(),與設定好的指令一一比較
const string sysCmds[CMD_NUM]={"cd","environ","jobs","help","echo","quit","exit","bye"}; //0表示失敗 1表示內部命令 2表示姓名int flag = 0;//內部命令的序號int index=-1;for(int i=0;i<CMD_NUM;i++){if(cmd.find(sysCmds[i]) != string::npos){flag = 1;index = i;if(index != 0){f_path.clear();}else{if(cmd.size()>2){string path(cmd,3,cmd.size()-3);f_path = f_path+"/"+path;}}break;}}if(flag==0 && cmd.find("lin") != string::npos){flag = 2;}第三部分 指令邏輯設計
這一部分也是最難的一部分,分兩類說
第一類 需要子進程
cd:
cd指令的實現是最麻煩的,因為要實現PWD的改變,我想的是用系統自帶的ls命令,然后我的程序本身維護一個PWD路徑,每次給ls子進程傳入的參數都是基于我程序維護的PWD的絕對路徑,然后還需要注意的是用戶輸入的都會用cd前綴,需要處理一下,提取關鍵路徑,然后再合并到程序維護的PWD中,然后將新的PWD作為參數傳入ls子進程中,實現cd命令效果。然后如果輸入了其他指令,就把cd維護的PWD串清空。
核心代碼如下:
核心代碼2部分
if(index == 0) //cd{if(cmd.size()>2){cout<<"當前路徑:"<<f_path<<endl;execlp("/bin/ls","ls",f_path.c_str(),NULL);}else{execlp("/bin/ls","ls",NULL);}}environ:
調用系統的env指令,execlp("env","",NULL);
jobs:
調用系統的pstree -p指令,execlp("pstree","-p",NULL);
echo:
echo單獨說一下就是C++關于string用法,這是調用了string的構造函數,參數是cmd的[5, cmd.size())子串。
其余指令都是類似于echo,根據輸入簡單的處理一下,然后輸出。
實驗結果與分析
cd命令
environ命令
jobs命令
結果符合邏輯設計
小結與心得體會
本實驗是一個綜合性實驗,涉及到了Linux下的C/C++編程,Linux進程創建,不過因為對Linux系統下C/C++編程較為熟悉了,所以本實驗完成并未花費太長時間,主要是卡在cd指令如何實現比較好,同時對fork()函數的理解更加深入。同時對于Linux系統中shell命令行的執行過程有了更深入的了解。=w=
源代碼
#include <sys/types.h> #include <sys/wait.h> #include <cstdio> #include <unistd.h> #include <iostream> #include <string>#define CMD_NUM 8 using namespace std;const string sysCmds[CMD_NUM]={"cd","environ","jobs","help","echo","quit","exit","bye"}; //string.find("cd")!=string::nposint main() {string f_path;while(true){string cmd;cout<<"請輸入指令: ";getline(cin,cmd);//0表示失敗 1表示內部命令 2表示姓名int flag = 0;//內部命令的序號int index=-1;for(int i=0;i<CMD_NUM;i++){if(cmd.find(sysCmds[i]) != string::npos){flag = 1;index = i;if(index != 0){f_path.clear();}else{if(cmd.size()>2){string path(cmd,3,cmd.size()-3);f_path = f_path+"/"+path;}}break;}}if(flag==0 && cmd.find("lin") != string::npos){flag = 2;}switch(flag){case 0:printf("指令錯誤,請重新輸入,幫助請輸入 help\n");break;case 1:if(index < 0){printf("指令錯誤,請重新輸入,幫助請輸入 help\n");}else if(index < 3) //需要調用子進程{pid_t pid;/* fork a child process */pid = fork();if (pid < 0){/* error occurred */fprintf(stderr, "Fork Failed");return 1;}else if (pid == 0){/* 子進程 */if(index == 0) //cd{if(cmd.size()>2){cout<<"當前路徑:"<<f_path<<endl;execlp("/bin/ls","ls",f_path.c_str(),NULL);}else{execlp("/bin/ls","ls",NULL);}}else if(index == 1) //environ{execlp("env","",NULL);}else if(index == 2) //jobs{execlp("pstree","-p",NULL);}}else /* 父進程 */{/* 父進程將一直等待,直到子進程運行完畢*/waitpid(pid,NULL,0);}}else //不需要子進程{if(index == 3) //help{cout<<"RongLin's Shell:"<<endl;cout<<"cd [路徑] -列出該路徑下的文件"<<endl;cout<<"environ -列出系統的環境變量"<<endl;cout<<"jobs -查看當前進程樹"<<endl;cout<<"help -幫助文檔"<<endl;cout<<"echo [內容] -顯示 echo 后的內容且換行"<<endl;cout<<"quit -退出本shell"<<endl;cout<<"exit -退出本shell"<<endl;cout<<"bye -退出本shell"<<endl;}else if(index == 4) //echo{string text(cmd,5,cmd.size()-5);cout<<text<<endl;}else //quit exit bye{return 0;}}break;case 2:cout<<cmd<<",希望你開心每一天"<<endl;break;}}return 0;}總結
以上是生活随笔為你收集整理的操作系统课设之简单 shell 命令行解释器的设计与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qt5 窗体显示完毕信号_iPhone手
- 下一篇: php @touch,touch - [