国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

個性化的Linux命令解析器的設(shè)計與實(shí)現(xiàn)

2022-11-01 03:31:22
關(guān)鍵詞:解析器調(diào)用命令

劉 雍

(海南熱帶海洋學(xué)院 計算機(jī)科學(xué)與技術(shù)學(xué)院,海南 三亞 572022)

0 引言

在全球超級計算機(jī)操作系統(tǒng)TOP500強(qiáng)排行榜中,Linux操作系統(tǒng)的占比在最近幾十年一直呈現(xiàn)快速上升趨勢,且保持在85%以上[1]。又隨著移動互聯(lián)網(wǎng)的快速發(fā)展,Linux內(nèi)核亦越來越頻繁地被移植和使用到嵌入式、物聯(lián)網(wǎng)、樹莓派及Android等智能設(shè)備中[2-3], 不斷擴(kuò)展的Linux Socket網(wǎng)絡(luò)編程實(shí)現(xiàn)信息實(shí)時交互、在線存儲、實(shí)時監(jiān)控等,自然成了主要開發(fā)的方向[4],因此,對Linux的各種命令的整合和解析也隨之成為熱門的課題。

以Linux操作系統(tǒng)原理為導(dǎo)向,從內(nèi)核編程的角度,重新構(gòu)建Shell命令從讀取到執(zhí)行的各環(huán)節(jié),是命令解析器開發(fā)研究的核心,而解析和模擬的本質(zhì)則是一個對多進(jìn)程控制的過程[5-6]。針對Linux固有命令較多,并且相當(dāng)多的命令反而極少被使用的現(xiàn)狀[7],本研究給出了一種設(shè)計Shell解析命令器通用模型的思路與方法:即把使用頻率較高的命令整合在一個幫助界面,并提供記憶歷史命令等輔助功能, 以實(shí)現(xiàn)更安全、更友好、更個性化的定制服務(wù)。隨著程序版權(quán)意識越來越強(qiáng)[8],個性化設(shè)計亦是本研究的重點(diǎn)之一。

1 個性化命令解析器的功能與工作流程

個性化命令解析器用C語言編程設(shè)計,遵照Linux默認(rèn)的Bash Shell結(jié)構(gòu)特點(diǎn),處理終端命令從輸入、到解析直至執(zhí)行全過程。在確保能正常調(diào)用Linux固有的命令集的前提下[9],個性化命令解析器實(shí)現(xiàn)了一個自定義的常用命令的集合,提供“help”幫助界面,解析命令的功能及用法,且增設(shè)了命令記憶功能,其較之傳統(tǒng)的單一的字符界面,用戶操作方便,交互性較好。

設(shè)計個性化命令解析器的思路和步驟主要包括以下三個環(huán)節(jié)。

第一步,初始化解析器,提供個性化命令行提示格式,獲取當(dāng)前用戶信息、主機(jī)信息及目錄信息等;第二步,切割用戶輸入命令行,獲取命令及參數(shù),第一個字符串為命令字,其余依次是參數(shù)序列;第三步,對上一個步驟獲取的命令進(jìn)行解析,包括判斷、調(diào)用和執(zhí)行等環(huán)節(jié)。首先判斷命令與當(dāng)前有限的自定義的命令是否匹配,若匹配則執(zhí)行“help”分支,創(chuàng)建進(jìn)程調(diào)用自定義函數(shù)[10];否則,判斷命令是否為系統(tǒng)內(nèi)部命令,對肯定的情況進(jìn)行“內(nèi)部命令”分支,調(diào)用系統(tǒng)默認(rèn)的命令解析,以保證Linux內(nèi)部命令正常使用;若對以上兩種情況都無法識別的命令,將執(zhí)行“無法識別的命令”分支,返回系統(tǒng)出錯信息。程序設(shè)計重點(diǎn)在于自定義命令的函數(shù)框架及API調(diào)用[11],個性化命令解析器工作流程如圖1所示。

圖1 個性化命令解析器工作流程

2 主要算法與分析

2.1 初始化解析器

Linux 中Bash Shell的組成部分從左到右依次是:登陸時的用戶名、主機(jī)信息和當(dāng)前目錄[12]。其中,使用getpwuid函數(shù)獲取密碼數(shù)據(jù)庫結(jié)構(gòu)指針數(shù)據(jù)struct passwd*pw,后輸出passwd成員變量char*pw_name即為用戶登錄名;通過函數(shù)原型int uname(struct utsname*buf) ,獲取主機(jī)信息,utsname成員變量nodename即為主機(jī)名;獲取當(dāng)前路徑使用函數(shù)的原型 char*getcwd(char*buf,size_t size),但是該函數(shù)獲取的是當(dāng)前的絕對路徑,因而還需要把絕對路徑轉(zhuǎn)化為相對路徑;提示部分區(qū)分#與$,如果函數(shù)getuid()的返回值為0,代表是根用戶root輸出#,否則輸出$。以上四個部分用以下語句在一行內(nèi)輸出:

printf("[ly′%s@%s %s]%c",pw->pw_name,ptr,p,flag);

假如默認(rèn)終端的原格式為“[root@hntou user]#(絕對路徑為/home/user)”,命令解析器初始化后可顯示為“[ly′root@hntou user]#”,意為當(dāng)前root用戶ly,登錄主機(jī)hntou,所在的相對路徑是user的目錄,還可以改變終端顯示的字體顏色和背景顏色,實(shí)現(xiàn)個性化友好顯示。

2.2 分離命令與參數(shù)

在自定義的終端下,如何識別用戶輸入執(zhí)行的命令及其參數(shù)是關(guān)鍵步驟之一,這里使用切割的方法。方法是使用strtok函數(shù)按空格分離用戶輸入的字符串?dāng)?shù)據(jù)(回車結(jié)束),分割后的各部分分別賦值給指針數(shù)組,第一個字符數(shù)組argv[0]即為命令,后面argv[1]、argv[2]等為命令的參數(shù),可用語句printf("listargv[%d]:%s/n",cnt,p)測試用戶輸入后的分割情形,其結(jié)果如下所示。

Your cmd is:copy ./a /home/user/bak_a

listargv[0]:copy

listargv[1]:./a

listargv[2]:/home/user/bak_a

2.3 解析并執(zhí)行命令

把上一步結(jié)果中的命令(argv[0])及參數(shù)列表(argv[1],argv[2]等)傳遞給內(nèi)核,解析并調(diào)用對應(yīng)功能的函數(shù)。使用strncmp函數(shù)去匹配命令集,首先調(diào)用自定義函數(shù),即定制的個性化可執(zhí)行程序;其次調(diào)用Linux固有的內(nèi)部命令,本質(zhì)上使用fork()函數(shù)創(chuàng)建新的進(jìn)程,在子進(jìn)程中調(diào)用exec系列函數(shù)執(zhí)行新進(jìn)程[13],如使用以下語句:

execl("/bin/sh","sh","-c",argv[0],NULL);

最后,如果以上子進(jìn)程執(zhí)行不成功,意為命令argv[0]無法識別,或者參數(shù)出錯,系統(tǒng)則輸出出錯信息,讓父進(jìn)程回收子進(jìn)程資源。

3 個性化命令集

3.1 實(shí)現(xiàn)框架

根據(jù)圖1可知,當(dāng)前命令解析器提供了至少6個常用命令解析,命令字及相關(guān)功能,如表1所示。

表1 自定義命令解析表

如果以上自定義的命令函數(shù)全部寫在main()函數(shù)所在的.c的文件里,代碼量將會相當(dāng)龐大,而且不利于調(diào)度和功能擴(kuò)展,為了程序書寫方便,且優(yōu)化編譯,一般做法是書寫各命令解析為獨(dú)立的.c源文件,如mycd.c、list.c、copy.c等,而后把這些.c的文件包含到一個自定義的myshell.h的頭文件中,當(dāng)然.h文件中還包括相當(dāng)多函數(shù)調(diào)用的系統(tǒng)頭文件[14],而后編譯時,只編譯包含main()函數(shù)的主函數(shù)的一個.c文件。

3.2 實(shí)現(xiàn)實(shí)例

以更改用戶路徑這一子功能mycd的命令解析為例,給出各子功能基本通用的程序設(shè)計框架。

第一步,編寫核心文件mycd.c,主要任務(wù)是自定義函數(shù)void cd_cmd(char *path),函數(shù)名為cd_cmd,參數(shù)是用戶輸入的路徑字符串,即函數(shù)功能實(shí)現(xiàn)切換目錄(舊目錄)到用戶輸入的路徑(新目錄)中。根據(jù)Linux操作系統(tǒng)的原理,要對參數(shù)分情況討論,如符號“~”代表用戶家目錄,“.”代表當(dāng)前目錄,“..”代表上一級目錄,“/”代表根目錄。而且還要處理權(quán)限的問題,如普通用戶無法切換到根用戶家目錄。在切換目錄的實(shí)際操作中,主要步驟大約分三步,首先,獲取用戶信息包括其家目錄信息,取結(jié)構(gòu)體數(shù)據(jù)struct passwd,其中pw_dir成員變量是家目錄;其次,獲取當(dāng)前目錄,使用函數(shù)getcwd(),把獲取當(dāng)前工作目錄的絕對路徑,賦值給old_path地址變量;最后,切換目錄,語句strcopy(old_path,new_path)則先給new_path賦值,再調(diào)用chdir(new_path)系統(tǒng)函數(shù)切換到新路徑中。

第二步,把子功能的核心文件包含到自定義的主要頭文件myshell.h中,該實(shí)例使用#include “mycd.c”語句,方便主函數(shù)調(diào)用。

第三步,在包含有myshell.h頭文件的main函數(shù)中調(diào)用以上第一步的cd_cmd函數(shù)。

if(strncmp(argv[0],"mycd",4)==0) //如果argv[0]所代表的命令是mycd關(guān)鍵字

{

cd_cmd(argv[1]);//調(diào)用函數(shù)

continue;

}

同樣的方法,如果再新增一個文件刪除命令myrm的解析,則只需要再書寫一個獨(dú)立的myrm.c源文件,并在myshell.h的頭文件中加上一句 #include “myrm.c”,最后在main函數(shù)中調(diào)用即可。限于篇幅,其他命令解析就不在此贅述。

3.3 主函數(shù)的思路

為突出個性化友好界面,增強(qiáng)交互性,判斷(strcmp(arglist[0],"help/0")==0)則給出了幫助help命令,打開運(yùn)行終端并將一直處于運(yùn)行之中,所以總體來說,main()函數(shù)是一個while(1)的循環(huán)結(jié)構(gòu)。依次調(diào)用初始化終端函數(shù)、命令行字符串切割函數(shù)、各子功能主要函數(shù)、內(nèi)置命令函數(shù),調(diào)用正確則輸出執(zhí)行結(jié)果,否則輸出出錯信息[15]。主函數(shù)中用整型變量cmd_cnt為計數(shù)器,以記錄歷史命令的個數(shù),函數(shù)strcpy(history[cmd_cnt],cmd)則實(shí)現(xiàn)把所有的命令放置于一個字符串?dāng)?shù)組中。如在個性化的終端提示符下,如果用戶輸入是系統(tǒng)不能識別的EXIT命令,則輸出出錯信息“Command Error!”,且友好提示“You may need ′help′”,根據(jù)提示輸入“help”命令后,界面下顯示的正是自定義的主要命令集,對各命令功能均有描述,具體情形參考如下。

[root@hntou shell_test]# ./shell

[ly′root@hntou shell_test]#EXIT

Command Error!

You may need ′help′

[ly′root@hntou shell_test]#help

mypwd:展示目前工作目錄.

mycd:切換指定工作目錄.

copy:復(fù)制目錄或文件到指定位置.

myps:顯示進(jìn)程信息.

myls:顯示文件信息.

mytime:顯示進(jìn)程運(yùn)行時間.

mytree:顯示目錄結(jié)構(gòu).

myrm:遞歸刪除文件、文件夾.

mymv:移動、重命名文件、文件夾.

myline:顯示文件、文件夾內(nèi)全部文件的函數(shù).

myhis:顯示輸入歷史.

exit:退出shell.

上述主界面給出常用命令的幫助信息,界面友好,操作方便。個性化命令解析體現(xiàn)在以下四個方面:第一,功能全面,用戶可首選自定義的命令,也可以調(diào)用Linux固有內(nèi)部命令,如查看當(dāng)前目錄或文件信息,示例既使用了主界面提供的myls命令,也使用原ls命令驗(yàn)證,確保了Linux內(nèi)部命令不缺失;第二,增強(qiáng)了命令解析的交互性,如實(shí)現(xiàn)文件復(fù)制操作調(diào)用的是copy命令,比原cp命令更符合用戶的理解,且有操作成功的交互性提示;第三,可擴(kuò)展性較好,可根據(jù)用戶需要靈活增減相應(yīng)功能的命令;第四,由于Linux shell默認(rèn)不會記憶歷史命令[16],所以使用myhis命令方便查看歷史命令序列,相關(guān)操作參考如下。

[ly′root@hntou shell_test]#myls-l ./

-rwxr-xr-x 1 root root 53016 Jan 26 21:37 shell

-rw-r--r-- 1 root root 114 Jan 26 21:37 file

[ly′root@hntou shell_test]#copy file bak_file

Copy Finished!

[ly′root@hntou shell_test]#ls

bak_file file shell

[ly′root@hntou shell_test]#myhis

**Print Input History until now:**

EXIT

help

list-l ./

copy file bak_file

ls

myhis

[ly′root@hntou shell_test]#exit

Bye~

[root@hntou shell_test]#

4 結(jié)論

本研究遵照Linux用戶的使用習(xí)慣,構(gòu)造了對Linux常用命令重新解析的方法和思路,給出了C語言程序設(shè)計的模型,實(shí)現(xiàn)了Shell命令提示格式個性化顯示、命令解析多樣化、主界面友好的設(shè)計及記憶歷史命令等功能,框架嚴(yán)謹(jǐn),思路清晰,方法靈活。該命令解析器個性化特征突出,易于擴(kuò)展,在移動互聯(lián)網(wǎng)設(shè)備方面適用性會越來越好。

猜你喜歡
解析器調(diào)用命令
只聽主人的命令
基于多解析器的域名隱私保護(hù)機(jī)制
基于Wireshark的列控中心以太網(wǎng)通信協(xié)議解析器的研究與實(shí)現(xiàn)
核電項目物項調(diào)用管理的應(yīng)用研究
LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
如何防御DNS陷阱?常用3種DNS欺騙手法
移防命令下達(dá)后
一種基于無關(guān)DNS的通信隱私保護(hù)技術(shù)研究
電子世界(2018年14期)2018-04-15 16:14:25
基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
這是人民的命令
萝北县| 湄潭县| 武川县| 社会| 讷河市| 河东区| 平远县| 无极县| 西林县| 沙田区| 迁西县| 林西县| 霍邱县| 当阳市| 镇原县| 积石山| 三都| 剑川县| 江油市| 犍为县| 双峰县| 亚东县| 绥阳县| 神木县| 邓州市| 依兰县| 合水县| 安阳市| 杂多县| 古田县| 永靖县| 浏阳市| 海淀区| 日照市| 蒲城县| 乌拉特中旗| 彰化县| 长武县| 富顺县| 阳泉市| 望都县|