色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux實現簡易的Shell命令行解釋器

dyquk4xk2p3d ? 來源:入門小站 ? 作者:入門小站 ? 2023-03-30 10:00 ? 次閱讀

一、前言

來制作一個簡易的 [Shell 命令]行解釋器。

首先這是與 Shell 的互動::

ae1c7a54-ce8a-11ed-bfe3-dac502259ad0.png

用下圖的[時間軸]來表示事件的發生次序。其中時間從> > 左向右。shell 由標識為 sh 的方塊代表,它隨著時間的流逝從左向右移動。shell 從用戶讀入字符串 "ls"。shell 建立一個新的進程,然后在那個進程中運行 ls 程序并等待那個進程結束。

ae3edf4a-ce8a-11ed-bfe3-dac502259ad0.png

然后 shell 讀取新的一行輸入,建立一個新的進程,在這個進程中運行程序 并等待這個進程結束。所以要寫一個 shell,需要循環以下過程:

1. 獲取命令行

2. 解析命令行

3. 建立一個子進程(fork)

4. 替換子進程(execvp)

5. 父進程等待子進程退出(wait)

二、準備工作

1.輸出提示符

ae709f44-ce8a-11ed-bfe3-dac502259ad0.png

這里的提示字符為用戶名 @主機名 當前路徑# 直接打印出來作為提示所用

printf("用戶名@主機名當前路徑#");

這里沒有 n,會有緩沖區的問題,類似于我們之前所說的進度條所遇到的問題,可以用 fflush(stdout) 刷新緩沖區。

2. 輸入和獲取命令

輸入

我們需要輸入一連串命令,其中可能出現空格,所以不能使用 gets 函數,需要用到 fgets 函數,同時,可以定義一個 lineCommand[NUM] 數組

#defineNUM1024
charlineCommand[NUM];
char*s=fgets(lineCommand,sizeof(lineCommand)-1,stdin);
assert(s!=NULL);

但是打印的時候卻多換了一行,這是我們把 n 也讀取到了,直接進行處理即可, 清除最后一個 n

lineCommand[strlen(lineCommand)-1]=0;

可以通過打印看看效果和測試是否有 BUG

printf("test:%s
",lineCommand);
ae85b9c4-ce8a-11ed-bfe3-dac502259ad0.png

獲取

輸入之后,我們自然需要去進行獲取,我們需要分割命令行,這個地方用 strtok。把字符串切割成若干個子串:
strtok: 第一次直接傳遞參數,第二次則必須傳 NULL。且在最終 strtok 會返回 NULL。

ae99dc06-ce8a-11ed-bfe3-dac502259ad0.pngaec2e524-ce8a-11ed-bfe3-dac502259ad0.png

3.shell 運行原理

同時,在理解一下 shell 的運行原理:shell 內部提取命令行做分析,然后調用 exec. shell 執行命令必須通過創建子進程,如果不創建子進程會把我們所有的 shell 全部替換,所以執行命令時一般磁盤上的程序必須創建子進程。

4. 內建命令

我們在運行自己寫的 shell 的時候,發現輸入 cd … 輸入 cd path 等命令時發現路徑并沒有改變!

aee97ca2-ce8a-11ed-bfe3-dac502259ad0.png

沒有發生改變是因為自己寫的 shell 執行很多命令都要 fork() 創建子進程,讓子進程執行的 cd,子進程有自己的工作目錄,所以更改的子進程的目錄,子進程執行完畢,繼續用的是父進程,既 shell,并沒有影響父進程,所以并沒有改變。

對于 cd, 我們可以采用內建命令:不需要創建子進程執行,讓 shell 自己執行命令,稱為內建命令。本質就是執行系統接口,我們可以調用一個系統接口 chdir,可解決上述問題:

aefa5928-ce8a-11ed-bfe3-dac502259ad0.png
af185b26-ce8a-11ed-bfe3-dac502259ad0.png

5. 替換

采用 execvp 進行替換進程

pid_tid=fork();
assert(id!=-1);
if(id==0)
{
execvp(myargv[0],myargv);
exit(1);
}

三、整體代碼

 #include
#include
#include
#include
#include
#include
#include
#defineNUM1024
#defineOPT_NUM64
charlineCommand[NUM];
char*myargv[OPT_NUM];//指針數組
intlastcode=0;
intlastsig=0;
intmain()
{
while(1)
{
//1.輸出提示符
printf("lj@VM-8-2-centos當前路徑#");
fflush(stdout);
//2.獲取用戶輸入的命令,輸入的時候,用戶最后還輸入了

char*s=fgets(lineCommand,sizeof(lineCommand)-1,stdin);
assert(s!=NULL);
(void)s;//避免Linux認為s變量未使用,導致警告
//清除最后一個
;例如:abcd

lineCommand[strlen(lineCommand)-1]=0;
//printf("test:%s
",lineCommand);
//"ls-a-l-i"-->字符串分割-->"ls""-a""-l""-i"
myargv[0]=strtok(lineCommand,"");
inti=1;
if(myargv[0]!=NULL&&(strcmp(myargv[0],"ls")==0))
{
myargv[i++]=(char*)"--color=auto";
}
//如果沒有子串了,strtok會返回NULL,即myargv[end]=NULL
while(myargv[i++]=strtok(NULL,""));
//如果是cd命令,不需要創建子進程,讓shell自己執行對應的命令,本質就是執行系統接口
//像這種不需要讓我們的子進程來執行,而是讓shell自己執行的命令—內建命令
//其中echo是一個自建命令
if(myargv[0]!=NULL&&(strcmp(myargv[0],"cd")==0))
{
if(myargv[1]!=NULL)chdir(myargv[1]);
continue;
}
if(myargv[0]!=NULL&&myargv[1]!=NULL&&(strcmp(myargv[0],"echo")==0))
{
if(strcmp(myargv[1],"$?")==0)
{
printf("%d,%d
",lastcode,lastsig);
}
else
{
printf("%s
",myargv[i]);
}
continue;
}
//利用條件編譯測試是否成功
#ifdefDEBUG
for(inti=0;myargv[i];++i)
{
printf("myargv[%d]:%s
",i,myargv[i]);
}
#endif
//執行命令
pid_tid=fork();
assert(id!=-1);
if(id==0)
{
execvp(myargv[0],myargv);
exit(1);
}
intstatus=0;
pid_tret=waitpid(id,&status,0);
assert(ret>0);
(void)ret;
lastcode=(status>>8)&0xFF;
lastsig=status&0x7F;
}
return0;
}
af335782-ce8a-11ed-bfe3-dac502259ad0.png

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11319

    瀏覽量

    209830
  • 命令行
    +關注

    關注

    0

    文章

    78

    瀏覽量

    10405
  • Shell
    +關注

    關注

    1

    文章

    366

    瀏覽量

    23412
  • 進程
    +關注

    關注

    0

    文章

    203

    瀏覽量

    13965
  • 解釋器
    +關注

    關注

    0

    文章

    103

    瀏覽量

    6542

原文標題:Linux 實現簡易的 Shell 命令行解釋器

文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    在STM32實現命令行

    工作中的開發環境都是基于linux命令行交互,作為命令行的重度使用者,玩單片機也要使用命令行工具,百度了一些命令行工具,有幾個不錯的開源 c
    發表于 12-09 11:32 ?2460次閱讀

    Linux圖形界面的原理與構成和Linux命令行和vi編輯的使用手冊

    本文檔的主要內容詳細介紹的是Linux基礎教案主要內容是:(1) 了解Linux圖形界面的原理與構成;(2)掌握Linux命令行操作,包括:命令行
    發表于 10-16 14:49 ?6次下載
    <b class='flag-5'>Linux</b>圖形界面的原理與構成和<b class='flag-5'>Linux</b><b class='flag-5'>命令行</b>和vi編輯<b class='flag-5'>器</b>的使用手冊

    Linux桌面系統初級教程之Shell命令行操作的資料概述

    Linux shell指的是一種程序,有了它,用戶就能通過鍵盤輸入指令來操作計算機了。Shell會執行用戶輸入的命令,并且在顯示上顯示執行
    發表于 11-09 17:42 ?18次下載
    <b class='flag-5'>Linux</b>桌面系統初級教程之<b class='flag-5'>Shell</b><b class='flag-5'>命令行</b>操作的資料概述

    Linux 命令行教程好書推薦

    今天跟大家推薦個 Linux 命令行教程:《The Linux Command Line》,中文譯名:《Linux 命令行大全》。 該書作者
    的頭像 發表于 02-14 09:25 ?1485次閱讀

    mini shell命令行調試工具(單片機、c語言)

    @mini shell命令行調試工具介紹Mini shell 命令行調試工具(單片機、c語言)Mini shell是一個特別適合低內存的單片
    發表于 11-29 10:21 ?10次下載
    mini <b class='flag-5'>shell</b><b class='flag-5'>命令行</b>調試工具(單片機、c語言)

    Shell命令行解釋簡介

    Shell 是一個命令行解釋Shell 為用戶提供了與設備進行命令行交互的方式,用戶通過串口
    的頭像 發表于 08-19 17:20 ?3243次閱讀

    Linux命令行shell腳本編寫

    Linux命令行shell腳本編寫
    發表于 01-11 16:50 ?4次下載

    如何在Linux命令行中運行Python腳本

    Python 是一種高級編程語言,被廣泛應用于數據科學、機器學習、Web 開發等領域。在 Linux 操作系統中,Python 是一個默認安裝的解釋,用戶可以通過命令行界面(CLI)
    的頭像 發表于 05-12 14:49 ?1699次閱讀

    單片機上如何做shell命令行交互

    做個shell命令行交互?答案當然是可以的,在網上類似的文章和代碼一搜一籮筐, 基本原理: 監測用戶的輸入,然后到一個命令查找表里過濾是否可以找到該命令,如果可以則調用對應的處理函數,
    的頭像 發表于 11-01 15:16 ?1423次閱讀

    shell命令linux命令一樣嗎

    Shell命令Linux命令并不完全一樣。 首先,Shell是一種命令行
    的頭像 發表于 11-08 10:51 ?2907次閱讀

    linux命令shell編程有什么聯系

    Linux命令Shell編程之間存在密切的聯系。 首先,ShellLinux命令行下的
    的頭像 發表于 11-08 10:53 ?944次閱讀

    linux命令行shell編程實戰

    Linux命令行Shell編程實戰主要涉及以下內容: Linux命令行基礎:學習Linux
    的頭像 發表于 11-08 10:57 ?794次閱讀

    linux虛擬機怎么調出命令行

    Linux虛擬機中調出命令行界面,可以通過以下步驟實現: 打開虛擬機,進入到Linux系統。 在桌面或應用菜單中找到終端或命令行圖標,點擊
    的頭像 發表于 11-08 11:28 ?3146次閱讀

    linux切換到命令行模式

    Linux中,可以通過以下步驟切換到命令行模式: 打開終端。可以在應用菜單中找到終端或命令行終端。 在終端中輸入命令“exit”或“logout”,然后按回車鍵。 系統會提示您輸入管
    的頭像 發表于 11-13 16:47 ?1803次閱讀

    linux命令行運行步驟

    運行Linux命令行涉及以下步驟: 打開終端 在Linux系統中,打開命令行界面的方式有多種,最常見的是打開終端應用程序。可以在應用程序菜單中找到終端,點擊打開。 熟悉
    的頭像 發表于 11-17 10:18 ?811次閱讀
    主站蜘蛛池模板: 久久久久伊人| 女人的选择hd| 国产精品熟女人妻| qvod欧美电影| h片下载地址| 97视频免费在线观看| 在线观看亚洲专区5555| 亚洲欧美国产视频| 亚洲欧洲精品A片久久99| 亚洲国产精品免费线观看视频| 天天国产在线精品亚洲| 午夜一区欧美二区高清三区| 天天操人人射| 幺妹视频福利视频| 99国产精品| 粗大分开挺进内射| 国产一卡 二卡三卡四卡无卡乱码视频| 国产亚洲视频中文字幕| 久久久久免费视频| 强奷表妺好紧2| 伸到同桌奶罩里捏她胸h| 亚洲 日韩 色 图网站| 2019伊人查蕉在线观看| 国产成人精品亚洲线观看| 久久婷婷五月免费综合色啪| 日韩娇小性hd| 羽月希被黑人吃奶dasd585| 99久久亚洲精品影院| 国产高清亚洲| 蜜柚视频网在线观看免费| 久久国产精品永久免费网站| 欧美高清vivoesosexo18| 向日葵视频app下载18岁以下勿看| 中文字幕无线手机在线| 国产精品久久自在自2021| 麻婆豆腐传媒视频免费| 无套内射无矿码免费看黄| 99精品免费久久久久久久久日本| 国产一区二区三区影院| 日本wwwxx爽69护士| 51精品少妇人妻AV一区二区|