freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

linux命令解釋器的設(shè)計(jì)本科畢業(yè)論文(編輯修改稿)

2025-07-16 14:13 本頁(yè)面
 

【文章內(nèi)容簡(jiǎn)介】 指針等進(jìn)行相應(yīng)的初始化。初始化的工作在程序中主要是由函數(shù)init_environ來(lái)進(jìn)行的。void init_environ(){ int fd,n,i。 char buf[80]。 if((fd = open(myshell_profile,O_RDONLY,660)) == 1){ printf(init environ variable error\n)。 exit(1)。} while (n = line(fd,buf)){ getenviron(n,buf)。} = 0。 = 0。 head = end = NULL。}在上面的程序中我們看到函數(shù)打開(kāi)一個(gè)名字是myshell_profile的自己編寫的文件,這是一個(gè)剛開(kāi)始的配置文件,用戶自己把配置的路徑寫到這個(gè)文件中。然后調(diào)用了另外兩個(gè)函數(shù)line (fd,buf]和getenviron(n,buf)。line(fd,buf)的作用是讀取行的信息到buf中。getenviron(n,buf)的主要作用是讀取line(fd,buf)讀取的命令,然后用冒號(hào)分隔開(kāi)buf中的信息,將命令各自放在envpath[]中,等待后面查找命令時(shí)在envpath[]中尋找命令。這樣命令前期初始化工作就已經(jīng)完成了。然后初始化history命令中鏈表的頭指針和尾指針,同樣將jobs命令中的頭指針和尾指針?lè)謩e指為空,head=end=NULL。到現(xiàn)在為止,我們所做的程序的前期準(zhǔn)備工作已經(jīng)大概做完了。然后,就會(huì)進(jìn)行while循環(huán),與普通的shell命令解釋器是一樣的,當(dāng)命令之行結(jié)束,或者將這個(gè)命令放在后臺(tái)執(zhí)行,用戶就可以重新輸入新的命令行,shell可以重頭開(kāi)始重復(fù)原來(lái)的工作。解析指令時(shí),對(duì)輸入到數(shù)組input的命令內(nèi)容完成解析,然后得到該命令和對(duì)應(yīng)的參數(shù)。shell中的命令分成4種:重定向命令,普通命令(外部命令),管道命令和內(nèi)部命令。但是由于管道和重定向命令比較復(fù)雜,所以對(duì)管道和重定向命令需要另外來(lái)處理。for(i = 0,j = 0,k = 0。i=input_len。i++){ if(input[i] == 39。39。||input[i] == 39。39。||input[i] == 39。|39。){ if(input[i] == 39。|39。){ pipel(input,input_len)。 add_history(input)。 free(input)。}else{ redirect(input,input_len)。 add_history(input)。 free(input)。} is_pr = 1。 break。 }}該程序中用for循環(huán)將帶有字符“”,“”和“|”符號(hào)的管道和重定向命令進(jìn)行另外的完成。然后定義一個(gè)is_pr,這是管道和重定向的命令標(biāo)志,置為1。然后分別調(diào)用redirect(input,input_len)和pipel(input,input_len)兩個(gè)函數(shù)來(lái)處理這兩類命令。對(duì)于普通的命令,當(dāng)檢測(cè)到is_pr的值是0的時(shí)候,就進(jìn)行下面的程序,下面的代碼就是主要普通命令和內(nèi)部命令進(jìn)行處理。for(i = 0,j = 0,k = 0。i=input_len。i++){ if(input[i] == 39。 39。||input[i] == 39。\039。){ if(j == 0) continue。 else{ buf[j++] = 39。\039。 arg[k] = (char *) malloc(sizeof(char)*j)。 strcpy(arg[k++],buf)。 j = 0。 }}else{ if(input[i] == 39。amp。39。 amp。amp。 input[i+1] == 39。\039。){ is_bg = 1。 continue。 } buf[j++] = input[i]。上面程序的for循環(huán)的作用就是對(duì)input數(shù)組中的命令進(jìn)行分析。當(dāng)用戶輸入空格時(shí),就會(huì)區(qū)分命令和參數(shù),如:“l(fā)s l”。這個(gè)例子的作用就是將這條命令的ls首先存儲(chǔ)到arg[0],而參數(shù)l則存儲(chǔ)在arg[1]。但是對(duì)于input數(shù)組的解析是要符合以下的規(guī)則的:以空格分段,分別放在arg[i]中。當(dāng)這個(gè)for循環(huán)運(yùn)行過(guò)后,數(shù)組argv[0]中的內(nèi)容就非常重要了,可以對(duì)數(shù)組arg[0]的內(nèi)容來(lái)分辨輸入的到底是內(nèi)部命令還是外部命令。判斷是內(nèi)部命令的話,就會(huì)執(zhí)行相對(duì)應(yīng)的操作。當(dāng)我們檢測(cè)到的命令不是內(nèi)部命令,也不是重定向命令和管道命令,就可以判斷是外部命令了。對(duì)于外部命令的處理就是查找該命令的執(zhí)行文件。if(is_pr == 0){ arg[k] = (char *)malloc(sizeof(char))。 arg[k] = NULL。 if(is_founded(arg[0]) == 0){ printf(This mand is not founded!\n)。 for(i = 0。i=k。i++) free(arg[i])。 continue。 }}is_founded函數(shù)就是用來(lái)來(lái)判斷輸入的外部命令的文件是不是已經(jīng)存在。函數(shù)如下:int is_founded(char *cmd){ int k = 0。 while(envpath[k]!=NULL){ strcpy(buf,envpath[k])。 strcat(buf,cmd)。 if(access(buf,F_OK) == 0) return 1。 k++。 } return 0。}當(dāng)我們對(duì)程序初始化的時(shí)候,我們已經(jīng)將命令以及其對(duì)應(yīng)的路徑已經(jīng)存儲(chǔ)到數(shù)組envpath[i]中,所以下面的工作就比較好做了,就直接在相對(duì)應(yīng)的路徑下查找和判斷輸入命令到底有沒(méi)有存在。如果找到返回l,沒(méi)有則返回0。當(dāng)我們判斷的時(shí)后就用到了access系統(tǒng)調(diào)用函數(shù)。格式 include int access(const char *pathname,int mode)。 參數(shù)說(shuō)明 pathndme是文件名稱。我們要判斷mode的屬性,可以取它們之間的組合或者是直接取值,文件可以讀用R_OK表示,文件可以寫用W_OK表示,文件可以執(zhí)行用X_OK表示,文件存在則用F_OK表示,當(dāng)函數(shù)的返回值為0時(shí),測(cè)顯示測(cè)試成功,否則返回值為1。當(dāng)輸入的命令被查找到時(shí),就把相應(yīng)的命令和路徑放到數(shù)組buf中。然后就直接執(zhí)行命令。當(dāng)我們查找到命令文件時(shí),就可以繼續(xù)執(zhí)行該命令內(nèi)容了。這時(shí),首先要新建一個(gè)子進(jìn)程,在該子進(jìn)程中執(zhí)行那個(gè)命令。fork創(chuàng)建一個(gè)新的子進(jìn)程的時(shí)候,該進(jìn)程會(huì)把其對(duì)應(yīng)的父進(jìn)程的堆棧和數(shù)據(jù)都繼承下來(lái),以及用戶的ID、環(huán)境變量等,還有工作的目錄等等。其實(shí)Linux會(huì)使用一個(gè)稱作COW的技術(shù),該技術(shù)是當(dāng)中間有一個(gè)進(jìn)程如果想要修改所復(fù)制的空間時(shí),才會(huì)真正的做復(fù)制動(dòng)作。子進(jìn)程的數(shù)據(jù)發(fā)生變化時(shí),父進(jìn)程的數(shù)據(jù)是不會(huì)由于子進(jìn)程當(dāng)中的數(shù)據(jù)變化而改變自身的數(shù)據(jù)的。當(dāng)一個(gè)子進(jìn)程創(chuàng)建完成后,父進(jìn)程中的pid號(hào)就是其子進(jìn)程的真正的ID號(hào),但是創(chuàng)建失敗時(shí),就會(huì)返回值為1。 這一段程序如下:If((pid = fork()) == 0)Execv(buf,arg)。ElseIf(is_bg== 0)Waitpid(pid,amp。status,0)。這幾行代碼運(yùn)行后就可以執(zhí)行外部命令。這里用到了兩個(gè)系統(tǒng)凋用函數(shù)execv和waitpid。函數(shù)waitpid格式:pid_t waitpid(pid_t pid,int *status,int options)。當(dāng)一個(gè)命令是前臺(tái)執(zhí)行的,那么其父進(jìn)程則必須執(zhí)行函數(shù)waitpid,而且必須等待子進(jìn)程,只有當(dāng)子進(jìn)程結(jié)束后,父進(jìn)程才可以執(zhí)行。后臺(tái)執(zhí)行恰恰不需要等待子進(jìn)程的完成就可以繼續(xù)執(zhí)行,就不需要waitpid。這就是前后臺(tái)命令的差別。waitpid所等待的子進(jìn)程由它的第個(gè)參數(shù)pid決定。因?yàn)閜id就是他父進(jìn)程中子進(jìn)程的id號(hào)。只有當(dāng)其對(duì)應(yīng)的子進(jìn)程執(zhí)行結(jié)束后,父進(jìn)程才可以繼續(xù)運(yùn)行。程序?qū)懙竭@,那么一個(gè)比較簡(jiǎn)便的shell命令解釋器基本寫完了,但是它只局限于內(nèi)部命令和外部命令,為了完善它的功能,還需要增加很多東西和代碼。但是基本的shell的思想大致就是這樣的。函數(shù)intpipel就是實(shí)現(xiàn)shell管道程序的函數(shù)。同以上的步驟差不多,該函數(shù)也需要命令的解析,尋找文件,和執(zhí)行以及釋放空間?;镜乃枷胧遣粫?huì)改變的。其實(shí)對(duì)于管道,跟重定向是由異曲同工指出的,都需要系統(tǒng)調(diào)用函數(shù)來(lái)是子進(jìn)程的文件描述符改變,就是dup2函數(shù)。初始化文件描述符IPE:define NO_PIPE 1define FD_READ 0define FD_WRITE 1for(i = 0。i=10。i++){ fd[i][FD_READ] = NO_PIPE。 fd[i][FD_WRITE] = NO_PIPE。}其中fd[i][FD_READ]和fd[i][FD_WRITE]都是int類型的文件描述符。上面已經(jīng)提到過(guò),管道是有相應(yīng)的讀端和寫端,所以fd[i][0]是管道讀端的入口,fd[i][1]就是管道寫端的入口。用fd[i][FD_READ]和fd[i][FD_WRITE]是為了方便閱讀。這個(gè)循環(huán)初始化了10對(duì)指向NO_PIPE(1)的文件描述符。1)建立管道我們?cè)谶@里分別定義了pipe_out和pipe_in這兩個(gè)文件描述來(lái)描述管道的寫端和讀端。從管道的讀端進(jìn)行輸入,寫端進(jìn)行輸出。我們用pipe_in來(lái)表示管道的讀端:/****************將pipe_in指向管道的讀端**************/ if(i != 0) pipe_in = fd[i1][FD_READ]。 else pipe_in = NO_PIPE。/****************將pipe_out指向管道的寫端**************/ if(i != li_cmd) pipe_out = fd[i][FD_WRITE]。把這兩段程序都在一個(gè)for的循環(huán)來(lái)使用,然后將pipe_in指向管道的讀端(除了首命令),將pipe_out指向管道的寫端(除了最后一條命令)。因?yàn)楣艿酪呀?jīng)建立完成了,然后進(jìn)程的輸出就寫到管道當(dāng)中,將標(biāo)準(zhǔn)輸出直接重定向到管道的寫端標(biāo)準(zhǔn)輸入重定向到讀端,最后我們就可以讀到管道當(dāng)中的數(shù)據(jù)了。 if(pid == 0){ if(pipe_in == NO_PIPE) close(pipe_in)。 if(pipe_out == NO_PIPE) close(pipe_out)。 if(pipe_out!=NO_PIPE){ dup2(pipe_out,1)。 close(pipe_out)。} if(pipe_in!=NO_PIPE){ dup2(pipe_in,0)。 close(pipe_in)。 } execv(buf,argv[i])。}else{ if(is_bg == 0) waitpid(pid,NULL,0)。 close(pipe_in)。 close(pipe_out)。 }管道命令就可以實(shí)現(xiàn)了。作業(yè)控制的主要命令包括三個(gè):jobs、bg和fg等。jobs命令jobs的實(shí)現(xiàn),要用到鏈表。每次建立一個(gè)后臺(tái)的作業(yè)或者當(dāng)一個(gè)作業(yè)被掛起的時(shí)候,鏈表中會(huì)創(chuàng)建一個(gè)與其相對(duì)應(yīng)的節(jié)點(diǎn),因此,當(dāng)用戶執(zhí)行一個(gè)命令,該命令是建立一個(gè)后臺(tái)運(yùn)行的作業(yè),作業(yè)控制就要在該鏈表的末端創(chuàng)建一個(gè)節(jié)點(diǎn),然后把作業(yè)的數(shù)據(jù)內(nèi)容儲(chǔ)存在該節(jié)點(diǎn)中。當(dāng)用戶輸入jobs命令行時(shí),然后就要把鏈表中的所有的作業(yè)信息都要顯示到控制臺(tái)中,還有作業(yè)號(hào),運(yùn)行狀態(tài)和名字。bg和fg命令我們定義了一個(gè)Ctrl+Z函數(shù),這個(gè)函數(shù)和fg、bg之間都是相關(guān)的,
點(diǎn)擊復(fù)制文檔內(nèi)容
物理相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖片鄂ICP備17016276號(hào)-1