日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

编写自己的Shell解释器-3[转]

發布時間:2025/3/13 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编写自己的Shell解释器-3[转] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

實現shell實例

程序主框架

???????主程序很簡單,它在做一些必要的初始化工作之后,進入這樣一個循環:

u???????打印提示符并等待用戶輸入

u???????獲取用戶輸入

u???????分析用戶輸入

u???????解釋執行;

如果用戶輸入 logout或者 exit 之后,才退出這個循環。

用類似偽代碼的形式表示如下:

while(1) {

???????print_prompt();

???????get_input();

???????parse_input();

???????if(“logout” || “exit”)

??????????????break;

???????do_cmd();

}

?

讀取用戶輸入

如何獲取用戶輸入?一種方法是通過 getchar() 從標準輸入每次讀一個字符,如果讀到的字符是 ‘\n’,說明用戶鍵入了回車鍵,那么就把此前讀到的字符串作為用戶輸入的命令。

代碼如下:

?

int len = 0;

int ch;

char buf[300];

?

ch = getchar();

while(len < BUFSIZ && ch != '\n') {

???????buf[len++] = ch;

???????ch = getchar();

}

if(len == BUFSIZ) {

???????printf("command is too long\n");

???????break;

}

buf[len] = '\n';

len++;

buf[len] = 0;

?

但是,我們注意到,在 bash 中,可以用“<-”和“->”鍵在命令行中左右移動,可以用上下鍵調用以前使用的命令,可以用退格鍵來刪除一個字符,還可以用 tab 鍵來進行命令行補全。我們的shell如果也要支持這些功能,那么就必須對這些鍵進行處理。這樣僅僅對用戶輸入的讀取就非常麻煩了。

實際上,任何需要一個獲取用戶輸入的程序,都會涉及到同樣的問題,如何象bash 那樣處理鍵盤?GNU readline 庫就是專門解決這個問題的,它把對鍵盤的操作完全封裝起來,對外只提供一個簡單的調用接口。有了它,對鍵盤的處理就不再讓人頭疼了。

關于 readline 庫的詳細信息,可以通過 man readline 來看它的幫助頁面。在我們的 shell 程序中,我是這樣來使用 readline的。

?

char* line;

char prompt[200];

while(1) {

???????set_prompt(prompt);

???????if(!(line = readline(prompt)))

??????????????break;

???????。。。。。。

}

?

首先通過 set_prompt() 來設置要輸出的提示符,然后以提示符作為參數調用 readline(),這個函數等待用戶輸入,并動態創建一塊內存來保存用戶輸入的數據,可以通過返回的指針 line 得到這塊內存。在每次處理完用戶輸入的命令之后,我們必須自己負責來釋放這塊內存。

有了 readline 之后,我們就可以象 bash 那樣使用鍵盤了。

在通過 readline 獲取用戶輸入之后,下一步就是對用戶輸入的命令進行分析。

?

命令行分析

對命令行的分析,實際上是一個詞法分析過程。學過編譯原理的朋友,都聽說過 lex 和yacc 的大名,它們分別是詞法分析和語法分析工具。Lex 和 yacc 都有GNU的版本(open source 的思想實在是太偉大了,什么好東東都有免費的用),分別是 flex 和 bison。

所謂“工欲善其事,必先利其器”,既然有這么好的工具,那我們就不必辛辛苦苦自己進行詞法分析了。對,我們要用 lex 來完成枯燥的命令行詞法分析工作。

“去買本《lexyacc》(中國電力出版社)來看吧。第一次學當然稍微有點難度,不過一旦掌握了,以后再碰到類似問題,就可以多一個利器,可以節省勞動力了

在我們的這個 shell 程序中,用 flex 來完成詞法分析工作。相對語法分析來說,詞法分析要簡單的多。由于我們只是做一個簡單的 shell,因此并沒有用到語法分析,而實際上在 bash 的實現代碼中,就用到了語法分析和 yacc。

關于 lex 的細節,在這里我就不能多說了。Lex程序,通常分為三個部分,其中進行語法分析工作的就是它的第二部分: “規則”。規則定義了在詞法分析過程中,遇到什么樣的情況,應該如何處理。

詞法分析的思路,就是根據前面定義的“shell語法規范”來把用戶輸入的命令行拆解成

首先,我們要把用戶輸入的命令,以空白字符(tab鍵或者空格)分隔成一個個的參數,并把這些參數保存到一個參數數組中。但是,這其中有幾種特殊情況。

一、如果遇到的字符是;”、“>”、“<”或“|,由于這些符號是管道或者列表中所用到的分隔符,因此必須把它們當作一個單獨的參數。

二、以雙引號(括起來的字符串要作為一個單獨的參數,即使其中出現了空白字符、“;”、“>”、“<”、“|”。其實,在POSIX標準中,對引號的處理相當復雜,不僅包括雙引號(”),還有單引號(’)、反引號(`),在什么情況下,應該用什么樣的引號以及對引號中的字符串應該如何解釋,都有一大堆的條款。我們這里只是處理一種極簡單的情況。

?

其次,如果我們遇到換行符(’\n’),那么就結束本次命令行分析。根據前面定義的 shell 語法規范,最上層的是列表命令,因此下一步是把所有的參數作為一個列表命令來處理。

轉載于:https://www.cnblogs.com/aoogur/archive/2008/12/05/1348723.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的编写自己的Shell解释器-3[转]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。