基于Linux下的MyBash命令解釋器

項目介紹:?個?C語?實現的簡單shell,可以接受??輸?的命令并執?操作,?持多管道和重 定向。

mybash---打造自己的命令解釋器
目前我們Linux的系統默認的命令解釋器是bash;?
命令解釋器(也稱為命令行解釋器或shell)是計算機操作系統中的一個重要組件,它負責接收用戶輸入的命令,并解釋和執行這些命令。其實命令解釋器就是解析命令,執行命令,輸出反饋;

1.命令的分類

內置命令和普通命令
1.內置命令:cd exit
2普通命令:ls pwd cp ps ??等等
如果是普通命令,那么使用which是可以找到的,比如which ps;which ls;which pwd;which cp;
也就是普通命令是一個可執行程序.
但是我們找cd和exit是找不到的; ?因為內置命令cd,exit等它是在bash本身實現的;
而bash也是一個可執行程序,比如:which bash;
簡單來講,就是普通命令是通過fork+exec實現的;而內置命令是bash自身通過調用相應的接口實現的;

2.項目框架

3.strtok的介紹

字符串分割函數

注意:
strtok線程不安全,原因就是函數實現使用了一個static的變量(指針記錄下次分割的地址,再次調用要沿用上次的,所以需要靜態變量).
在多線程中,如果兩個線程都使用了strtok的話,這個變量的值就會被另一個線程不定期的進行修改.?

4.mybash.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>#define  ARG_MAX  10
char *get_cmd(char *buff,char *myargv[])
{if(buff==NULL||myargv==NULL){return NULL;}int i=0;char *s=strtok(buff," ");while(s!=NULL){myargv[i++]=s;s=strtok(NULL," ");}return myargv[0];
}
int main()
{while(1){printf("stu@loalhost:~$");fflush(stdout);char buff[128];fgets(buff,128,stdin);//ls  cd 路徑名    cp  a.c  b.cchar *myargv[ARG_MAX]={0};buff[strlen(buff)-1]='\0';//注意這一句,自己練習一下調試char *cmd=get_cmd(buff,myargv);//得到命令cmd和它的參數(cmd和參數一起放在了myargv)if(cmd==NULL){continue;}else if(strcmp(cmd,"cd")==0){//}else if(strcmp(cmd,"exit")==0){// exit(0);break;}///else{//普通命令//fork+exec}}//exit(0);
}

?代碼效果只能顯示出命令,并不能執行命令

5.進行進一步的修改

?對具體函數進行填充

int main()
{while(1){//    printf("stu@localhost        ~$");printf_info();//fflush(stdout);char buff[128]={0};fgets(buff,128,stdin);//ls,ps -f,cp a.c b.cbuff[strlen(buff)-1]='\0';char *myargv[ARG_MAX]={0};char *cmd=get_cmd(buff,myargv);if(cmd==NULL){continue;}else    if(strcmp(cmd,"cd")==0){//...if(myargv[1]!=NULL){if(chdir(myargv[1])==-1){perror("cd err!\n");}}}else if(strcmp(cmd,"exit")==0){//exit(0);//OK,不建議break;}else{//fork+exec;run_cmd(cmd,myargv);}}//...exit(0);
}
void  printf_info()
{char *user_str="$";int user_id=getuid();if(user_id==0){user_str="#";}struct passwd *ptr=getpwuid(user_id);if(ptr==NULL){printf("mybash1.0>>  ");fflush(stdout);return ;}char hostname[128]={0};if(gethostname(hostname,128)==-1){printf("mybash1.0>>  ");fflush(stdout);return ;}char dir[256]={0};if(getcwd(dir,256)==NULL){printf("mybash1.0>>  ");fflush(stdout);return ;}printf("\033[1;32m%s@%s\033[0m  \033[1;34m %s\033[0m%s ",ptr->pw_name,hostname,dir,user_str);fflush(stdout);
}

一次對用戶id ,主機名,當前目錄初始化和定義?更改后效果

現在我們完善普通命令:

void run_cmd(char *path,char *myargv[])
{if(path==NULL ||myargv==NULL){return ;}pid_t pid=fork();if(pid==-1){return ;}if(pid==0){execvp(path,myargv);perror("execvp   error!\n");exit(0);}else{wait(NULL);}}

運行結果如下:?

?實際上應用了exevp函數,讓操作系統自動調用了 /user/bin 文件里面的 各個普通命令實現mybash

完成一個借雞生蛋的過程

6.我們也可以寫出自己的二級制可執行程序,實現真正的mybash

例如 clear和pwd:

//clear.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main()
{printf("\033[2J\033[0;0H");
}//pwd.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main()
{char path[256]={0};if(getcwd(path,256)==NULL){   perror("getcwd  error!\n");exit(1);}   printf("%s\n",path);exit(0);
}

?并且更改路徑

還應PATH_BIN的位置

#define PATH_BIN "/home/stu/quzijie/test15/mybin/"

這是我自己文件地址

void run_cmd(char *path,char *myargv[])
{if(path==NULL ||myargv==NULL){return ;}pid_t pid=fork();if(pid==-1){return ;}if(pid==0){// execvp(path,myargv);char pathname[128]={0};if(strncmp(path,"/",1)==0||strncmp(path,"./",2)==0){strcpy(pathname,path);}else{strcpy(pathname,PATH_BIN);strcat(pathname,path);}execv(pathname,myargv);perror("execvp   error!\n");exit(0);}

?結果如下:

?7.總結

基于Linux內核的命令解釋程序(Shell),設計了?個??的MyBash命令解釋器。實現 了?致的程 序總框架,系統命令提?符顯?,對??輸?命令的解析和執?,其中區別了系統的內 置命令和外置命令。具體實現了:顯?指定?錄下?件列表ls 和ls的部分攜帶參數例如“-l”“-a”、 顯?當前位置的絕對路徑pwd、清除 clear以及exit

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/899302.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/899302.shtml
英文地址,請注明出處:http://en.pswp.cn/news/899302.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux常見使用場景

一、文件查看與內容操作 ?1. cat ?作用&#xff1a;查看文件內容&#xff08;一次性輸出全部內容&#xff09;。?常用選項&#xff1a; -n&#xff1a;顯示行號。-b&#xff1a;僅對非空行顯示行號。 ?示例&#xff1a; cat file.txt # 查看文件內容 cat -n fil…

Ingredient-oriented Multi-Degradation Learning for Image Restoration論文閱讀

摘要&#xff1a;重點在于關聯多個任務本質的聯系。 不同恢復任務的關聯性很重要。 揭示退化現象的內在機理聯系很有意義。 多合一的方法能在單一模型中處理多種退化問題&#xff0c;可擴展性較差。 成分導向范式挖掘不同圖像退化現象背后的物理規律或特征模式。 成分導向退化重…

禪道后臺命令執行漏洞

漏洞簡介 禪道是第一款國產的開源項目管理軟件。它集產品管理、項目管理、質量管理、文檔管理、 組織管理和事務管理于一體&#xff0c;是一款專業的研發項目管理軟件&#xff0c;完整地覆蓋了項目管理的核心流程。 禪道管理思想注重實效&#xff0c;功能完備豐富&#xff0c;…

密碼學——知識問答

目錄 1、闡述公開密鑰算法的定義&#xff0c;結合RSA算法說明公鑰密碼的基本要求。 說明公鑰與私鑰兩種密碼學并舉例與其應用 1. 公鑰密碼學&#xff08;非對稱加密&#xff09;&#xff1a; 2. 私鑰密碼學&#xff08;對稱加密&#xff09;&#xff1a; 對比公鑰與私鑰密碼…

PDF多表格結構識別與跨表語義對齊:基于對抗遷移的魯棒相似度度量模型

文章目錄 一. 項目結構二.流程分析2.1 批處理器核心代碼解析 三. 跨頁表格相似度匹配原理3.1 表頭內容相似度-特征向量歸一化3.2 表頭內容相似度-余弦相似度3.3 定時緩存清理 ocr掃描有其局限性。對于pdf文本類型這種pdfbox&#xff0c;aspose-pdf&#xff0c;spire直接提取文本…

es 3期 第27節-運用Script腳本實現復雜需求

#### 1.Elasticsearch是數據庫&#xff0c;不是普通的Java應用程序&#xff0c;傳統數據庫需要的硬件資源同樣需要&#xff0c;提升性能最有效的就是升級硬件。 #### 2.Elasticsearch是文檔型數據庫&#xff0c;不是關系型數據庫&#xff0c;不具備嚴格的ACID事務特性&#xff…

23、web前端開發之html5(四)

十二. HTML5實踐示例 前面我們詳細講解了HTML5的特點&#xff0c;包括語義化標簽、增強的表單功能、多媒體元素&#xff08;如<video>和<audio>&#xff09;、Canvas繪圖、SVG集成以及離線存儲等。以下是一些詳細的HTML5實踐示例&#xff0c;展示如何使用HTML5的新…

海思燒錄工具HITool電視盒子刷機詳解

HiTool是華為開發的一款用于海思芯片設備的刷機和調試工具&#xff0c;可對搭載海思芯片的機頂盒、智能電視等設備進行固件燒錄、參數配置等操作。以下為你詳細介紹&#xff1a; 功能用途 固件燒錄&#xff1a;這是HiTool最主要的功能之一。它能夠將下載好的適配固件文件燒錄到…

軟考中級-軟件設計師 23種設計模式(內含詳細解析)

23種設計模式 &#x1f3af; 創建型設計模式&#x1f4cc; 抽象工廠&#xff08;Abstract Factory&#xff09; 設計模式&#x1f4cc; 工廠方法&#xff08;Factory Method&#xff09;設計模式&#x1f4cc; 單例&#xff08;Singleton&#xff09;設計模式&#x1f4cc; 生成…

thinkphp8.0\swoole的websocket應用

環境&#xff1a;centOS7.9、php8.3、thinkphp8.0\think-swoole4.1 我用的官方think-swoole插件 第一步&#xff1a;根據官方文檔&#xff0c;需要安裝此擴展插件 composer require topthink/think-swoole 第二步&#xff1a;在根目錄下config文件夾下編輯swoole.php配置文…

Ubuntu服務器掛載時遇到文件系統錯誤怎么辦

在Ubuntu服務器上掛載分區時&#xff0c;如果遇到文件系統錯誤&#xff0c;通常可能是由于磁盤損壞、文件系統損壞、不正確的卸載等原因造成的。以下是詳細的排查與修復步驟&#xff1a; 一、查看錯誤信息 首先&#xff0c;嘗試手動掛載并觀察具體錯誤&#xff1a; sudo mount …

【設計模式】策略模式(Strategy Pattern)詳解

策略模式&#xff08;Strategy Pattern&#xff09;詳解 一、策略模式的定義 策略模式&#xff08;Strategy Pattern&#xff09;是一種行為型設計模式&#xff0c;它定義了一組算法&#xff0c;將每個算法封裝起來&#xff0c;并使它們可以相互替換&#xff0c;從而讓算法的…

軟考筆記5——軟件工程基礎知識

第五章節——軟件工程基礎知識 軟件工程基礎知識 第五章節——軟件工程基礎知識一、軟件工程概述1. 計算機軟件2. 軟件工程基本原理3. 軟件生命周期4. 軟件過程 二、軟件過程模型1. 瀑布模型2. 增量模型3. 演化模型&#xff08;原型模型、螺旋模型)4. 噴泉模型5. 基于構建的開發…

Vim 實用指南

導航 簡介Vim 的來歷Vim 語言 Vim 的三種模式Normal&#xff08;普通模式&#xff09;Insert&#xff08;插入模式&#xff09;Visual&#xff08;可視模式&#xff09;三種模式轉換 普通模式實用技巧說明復制當前行并粘貼使用上一個命令撤銷上一個操作最常用的跳轉命令查找對應…

Git入門——常用指令匯總

以下是一份精心整理的 Git常用指令速查表&#xff0c;基本覆蓋日常開發使用場景&#xff0c;建議收藏備用&#x1f447; &#x1f527; 環境配置 指令作用git config --global user.name "你的名字"設置全局用戶名git config --global user.email "你的郵箱&qu…

常見中間件漏洞攻略-Jboss篇

一、CVE-2015-7501-Jboss JMXInvokerServlet 反序列化漏洞 第一步&#xff1a;開啟靶場 第二步&#xff1a;訪問該接口&#xff0c;發現直接下載&#xff0c;說明接?開放&#xff0c;此接?存在反序列化漏洞 http://47.103.81.25:8080/invoker/JMXInvokerServlet 第三步&…

播放本地視頻-實現視頻畫廊功能

實現一個視頻畫廊&#xff0c;播放本地視頻 可以切換不同視頻的功能 文章目錄 需求&#xff1a;場景實現方案遇到的坑播放器選擇界面顯示不全視頻友好顯示問題緩存 總結 需求&#xff1a; 實現一個視頻畫廊&#xff0c;播放本地視頻 可以切換不同視頻的功能 場景 圖片畫廊的…

從零構建大語言模型全棧開發指南:第二部分:模型架構設計與實現-2.2.2文本生成邏輯:Top-k采樣與溫度控制

?? 點擊關注不迷路 ?? 點擊關注不迷路 ?? 點擊關注不迷路 文章大綱 2.2.2 文本生成邏輯:Top-k采樣與溫度控制1. 文本生成的核心挑戰與數學框架1.1 自回歸生成的基本流程2. `Top-k`采樣原理與工程實現2.1 數學定義與算法流程2.2 PyTorch實現優化3. 溫度控制的數學本質與參…

為什么后端接口返回數字類型1.00前端會取到1?

這得從axios中得默認值說起&#xff1a; Axios 的 transformResponse axios 在接收到服務器的響應后&#xff0c;會通過一系列的轉換函數&#xff08;transformResponse&#xff09;來處理響應數據&#xff0c;使其適合在應用程序中使用。默認情況下&#xff0c;axios 的 tran…

【C++游戲引擎開發】《線性代數》(2):矩陣加減法與SIMD集成

一、矩陣加減法數學原理 1.1 定義 ?逐元素操作:運算僅針對相同位置的元素,不涉及矩陣乘法或行列變換。?交換律與結合律: 加法滿足交換律(A + B = B + A)和結合律( ( A + B ) + C = A + ( B + C ) )。 ?減法不滿足交換律(A ? B ≠ B ? A)。1.2 公式 ? C i j = …