1. 程式人生 > >Shell專案:命令解析器

Shell專案:命令解析器

命令解析器:

       提示資訊:執行自己的Shell時,首先會像系統shell一樣,輸出一段提示資訊,

從左到右依次是:登陸時的使用者名稱,主機資訊,和當前目錄。

       我們定義一個函式Put Flag()來實現,

這裡涉及到幾個大家可能不太熟悉的函式和結構體

  

切割命令(識別命令):

輸出了提示資訊後,使用者就要輸入他想執行的命令了,那我們如何來識別使用者輸入的命令呢,又是怎樣識別使用者輸入的是引數還是命令呢,這裡我們實現一個CutCmd函式,顧名思義就是切割命令。

這裡strtok函式就是用來切割命令的函式,也是該函式的核心。第一次呼叫時必須將要切割的字串cmd傳進去,以空格為切割標記,細心的同學可能會發現在下面while迴圈中strtok函式的引數傳了一個NULL,這和strtok函式的實現機制有關。

strtok()在引數cmd的字串中發現第二個引數中包含的分割字元時,則會將該字元改為\0 字元。在第一次呼叫時,strtok()必需給予引數cmd字串,往後的呼叫則將引數cmd設定成NULL。每次呼叫成功則返回指向被分割出片段的指標cmd為空值NULL,則函式儲存的指標SAVE_PTR在下一次呼叫中將作為起始位置。

到這裡我們的準備工作差不多已經完善了,接下來就到了根據使用者輸入的命令去執行相關可執行檔案的時候了

程序替換和子程序:

       當用戶輸入命令後,我們要根據使用者輸入的命令去選擇相應的可執行檔案來實現該命令,這裡會用到一個exec函式,它實現了一個程序替換的功能,就是把當前程序的程式碼從呼叫該函式處替換成另外一個檔案,而程序號不變,在系統的終端程式中,一個命令執行完之後又會回到命令解析器中,也就是說命令解析器的主程式應該是一個死迴圈,但是如果呼叫exec函式替換程序之後,這個死迴圈就會退出,也就是說我們這個終端每次執行一個命令就要重新啟動一次,顯然與系統終端有很大差別,為了消除這一差異,我們在這裡使用fork函式產生一個子程序,然後把程序替換實現在子程序中,這樣,每執行完一個命令,子程序結束,又會回到父程序的命令解析器的死迴圈中。

這裡用紅色下劃線標註的是兩個不能在子程序中實現的命令,一個是exit,退出終端的命令,執行此命令後,終端程式結束,終端退出。還有一個是cd命令,切換當前目錄,如果在子程序中實現,當前目錄切換之後子程序結束,又會回到當前目錄,因此cd命令應該實現在父程序中。我們封裝了一個函式來實現cd命令

命令解析器基本就是這些內容,接下來就是各個命令的具體實現了。