編寫簡單的shell命令解析器

2021-04-27 01:31:32 字數 2928 閱讀 9436

編寫簡單的shell命令解析器

環境:redhat 9.0    核心 2.4.20

vi 文書編輯器  6.1.320

gcc  3.2.2-5

實現步驟:

第0步:寫乙個最簡單的shell命令直譯器,本程式取自apue例1-5,命令不能帶引數。

需要完成的內容如下:

命令直譯器首先是乙個死迴圈。

列印乙個命令提示符。

取得命令列輸入放在陣列裡面,不要求命令帶引數。可以getc()、fgets()、scanf()等。

如果用fgets()的話,取得的字串包括最後輸入的換行符,故要去掉命令字串末尾的「/n」,變成「/0」

。建立乙個子程序,呼叫exec執行命令。

父程序呼叫waitpid()等待子程序的退出,然後進入下一次迴圈。

第1步:寫乙個shell命令直譯器,使能處理帶引數的命令。

需要完成的內容如下:

命令直譯器首先是乙個死迴圈。

列印乙個命令提示符,

包含當前路徑資訊。取得命令列輸入,本程式是把命令列輸入儲存在乙個字元指標指向的位址中。

分析命令列,把以空格分開的命令和引數

分別取出來放在字元指標陣列arg中。這裡取得的命令列字串儲存在input指向的位址。為了把這一行字串中的命令和引數分開,需要乙個臨時陣列tmp(本程式是重用前面使用的buf陣列),把input指向命令列中的命令和引數分別儲存在arg[0]、arg[1]等等。

4 .  建立乙個子程序,呼叫exec執行命令。

5.   父程序(即shell命令直譯器)根據命令是在前台還是後台執行,決定是否呼叫waitpid()。然後進入下一次迴圈。

第2步:加入內部命令cd、exit。

需要完成的內容如下:

1.以第1步為基礎,在分析完命令列輸入後,看輸入的命令arg[0]是不是「exit」

或者「cd」

,如果是的話,在執行建立子程序去執行這個命令之前就做為內部命令執行。

2.exit命令的實現只要列印一句話「bye bye!」

,然後釋放前面分配的記憶體空間,然後退出即可。

3.cd命令的實現用到函式chdir(arg[1]),它用來改變當前工作目錄。

第3步:程式的實現分別放在幾個檔案中,引入標頭檔案的概念。引入重定向和管道函式,但不用具體實現這兩個函式。

需要完成的內容如下:

1.引入標頭檔案,把公共的變數和函式放在標頭檔案中,注意防止標頭檔案被重複包含。

2. 處理使用者輸入的命令列中包含重定向符號和管道符號的情況。使用函式redirect()和my_pipe()處理重定向和管道,這兩個函式的實現放在乙個單獨的檔案中,不用具體實現這兩個函式。

第4步:引入環境變數配置檔案mysh_profile,讀取環境變數,判斷檔案是否存在,若存在,執行命令,否則列印「command not found」

。需要完成的內容如下:

1.建立乙個環境變數配置檔案,裡面的內容是一行path環境變數如下:path=/bin:/sbin:/usr/bin:/usr/sbin

2.建立函式init_environ(),讀取環境變數到陣列。

3.建立函式is_founded(),查詢檔案,看檔案是否存在。

第5步:實現重定向功能。

需要完成的內容如下:

在redirect.c檔案中實現redirect()函式。

第6步:實現管道功能

需要完成的內容如下:

在pipe.c檔案中實現my_pipe()函式。

第7步:實現歷史記錄命令history

需要完成的內容如下:

1. 在標頭檔案mysh.h中增加表示歷史記錄的迴圈陣列的資料型別,並定義相應變數。

2. 在history.c中實現函式add_history()和history_cmd()。

3.在main.c中,分別在管道、重定向、內部命令、普通命令執行前,把命令列內容加入到命令歷史記錄迴圈陣列中。

第8步:實現後台作業佇列,加入內部命令jobs、bg、fg命令。

測試完成的功能:

第0步驟:

1. 要求每個命令完成後,重新列印出提示符

2. 測試:ls cat 等命令

第1步驟:引數

1. 提示符中出現當前路徑資訊。

2. 測試命令「ls」,「ls《空格》」,「《空格》ls」,「《空格》ls《空格》」

「ls -a -l」  ,「《空格》ls 《多個空格》 -a 《多個空格》-l」

第2步驟:cd exit

1. 測試"cd ..", "cd /home" , "cd -" , "cd~" 等命令

第4步驟:環境變數

1. 把/bin/ls檔案拷貝到/home目錄,

並將/bin/ls重新命名為/bin/ls-bk,測試ls命令

2.在環境變數檔案mysh_profile中新增"/home"目錄,測試ls命令

第5步驟:重定向

1. 測試 "ls>test" , "ls(空格)>(空格)test" , "ls(空格)>test"命令

2. 測試 "ls>>test" , "ls(空格)>>(空格)test" , "ls(空格)>>test"命令

3. 測試"cattesttest1> test"生成

第6步驟:管道

1. 測試"ls(空格)|(空格)more"命令

第7步驟:歷史記錄

1. 測試用上下鍵從歷史記錄中提取命令

第8步驟:作業管理

1. 測試jobs, bg , fg, "ctrl+c","ctrl+z" 命令

總結:這個專案主要涉及到的知識:程序控制、程序通訊。當然,c語言的基礎是最重要的。

專案的基本功能已實現,但存在一些待解決問題:1.歷史命令調出,對之進行增減後還不能執行相應的命令;2.jobs鍊錶的建立沒加上判斷條件,導致執行後台命令時鍊錶儲存重複的內容。

源**位置:

Linux shell 命令解析器

都說shell是基本功,打好地基才能建立上層建築。覺得自己對shell的掌握還不夠,希望能經過積累對其越發熟悉,可以良好的運用。shell 命令解析器 將使用者輸入的指令轉化為機器可以執行的程式。開頭要寫 bin bash sh 用bash sh解析 在shell指令碼中 後面加注釋。檔案存為fil...

2 shell命令解析器和環境變數

shell是乙個命令解析器,是用來解析命令的,或者說它是乙個程式,它是我們和linux系統互動的一種工具,當我們在終端輸入一系列的字串時,shell會接收它們,並且再終端顯示出來,當按回車鍵的時候,此時shell就會解析這些字串,並且會去尋找和字串對應的程式,最後執行程式,那麼問題來了,要去 尋找呢...

PE解析器的編寫(一) 總體說明

之前自己學習了pe檔案的格式,後來自己寫了個pe檔案的解析器,這段時間工作上剛好要用到它,老闆需要能檢視某個exe中載入的dll的乙個工具,我在使用之前自己寫的這個東西的時候,發現很多東西都忘記了,所以,我在這回顧下當時的思路,並記錄下來,方便以後直接使用。也算是回顧下之前學習的內容,將學的東西學以...