MiniShell的實(shí)現(xiàn)畢業(yè)設(shè)計(jì)_第1頁
MiniShell的實(shí)現(xiàn)畢業(yè)設(shè)計(jì)_第2頁
MiniShell的實(shí)現(xiàn)畢業(yè)設(shè)計(jì)_第3頁
MiniShell的實(shí)現(xiàn)畢業(yè)設(shè)計(jì)_第4頁
MiniShell的實(shí)現(xiàn)畢業(yè)設(shè)計(jì)_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、畢業(yè)設(shè)計(jì)(論文)題目:Mini Shell的實(shí)現(xiàn)學(xué)生姓名_學(xué)號 201022030121班級 計(jì)算機(jī) 102201H所屬院(系)計(jì)算機(jī)科學(xué)與技術(shù)系 指導(dǎo)教師_2014 年 5 月 20 日IMini Shell的實(shí)現(xiàn)摘要隨著 linux 系統(tǒng)的普及,越來越多的人在更深入地研究linux ,而對于微型 linux shell的研究是研究 linux 的重點(diǎn)。本文對 shell 的研究包括對其功能的了解,并實(shí)現(xiàn)對 shell 的列 表、管道、輸入重定向、輸出重定向等命令功能,可以比較全面地認(rèn)識shell 解釋器,并在shell 中執(zhí)行正確的命令,從而對它的功能、語法等在程序設(shè)計(jì)中必須用到的知識有了

2、較為 清晰的認(rèn)識, 最后通過對各個功能模塊的具體分析, 編寫出正確實(shí)現(xiàn)各個功能的代碼, 從 而完成一個簡易的 shell解釋器的模擬。而且,在嵌入式領(lǐng)域中,硬件資源是有限的,但是需求是無限的。這就意味著們要利 用有限的資源來完成各種各樣的需求,而嵌入式設(shè)計(jì)和在傳統(tǒng)的PC 上編程是有很大差異的,它往往只需要一個龐大程序的很小的一部分就可以滿足它的需求,所以我們不得不把 一些無用的程序裁剪掉來換取空間。 在嵌入式領(lǐng)域中像傳統(tǒng)的 K shell,C shell, Bourne Shell 等大型的 shell 程序就會使我們的硬件資源捉襟見肘。所以我們要有一個更適合嵌入式系統(tǒng) 中使用的 shell,

3、這也是我本次設(shè)計(jì)的另一個目的。關(guān)鍵詞:Shell;程序;設(shè)計(jì)與實(shí)現(xiàn);嵌入式2Mini Shell?s impleme ntati onAbstractAccompa nied by the popularize of the linux, more and more people are doing deeply study in it.The study of the shell in linux is the most importa nt thi ng whe n study the linux. And how to study? Itmainly in cludes the un d

4、ersta nd of some kno wledge and function of the micro linux shell. Throughthe study of the orders in shell like list, pipe, in put redirect and output redirect, readers can have athorough sense about the shell and lear n to use these orders accurately in shell which play animporta nt role in program

5、 ming later. Code accurately and achieve a simple shell with the fun cti onsabove after an alyz ing the details of every fun cti ons module.Moreover, in the embedded field, the hardware resources are limited, but dema nd is un limited.This means they have to use limited resources to accomplish a var

6、iety of n eeds, and embeddeddesig n and program ming in the traditi onal PC, is very differe nt, and it ofte n requires only a smallpart of a large program on meet its n eeds, so we had to cut out a nu mber of useless programs inexchange for space. In the embedded field, as the traditional K shell,

7、C shell, Bourne Shell and otherlarge-scale shell program will make our hardware resources are stretched. So we n eed a moresuitable for embedded systems used in the shell, this is my ano ther objective of this desig n.Key words: Shell, Process, Desig n and achieve, embedded3摘要.Abstract.II刖言.-1 -第一章S

8、hell 簡介.-2 -1.1 shell 的定義. -2 -1.1.1 UNIX Shell.- 3 -1.1.2 Li nuxShell.- 3 -1.2 shell 的歷史.-4 -1.3 shell 的職責(zé) .-5 -第二章 模擬 shell 設(shè)計(jì) .-6 -2.1 簡單 shell 設(shè)計(jì)思想 .-6 -2.2 復(fù)雜 shell 設(shè)計(jì)思想 .-7 -2.2.1 作業(yè)及作業(yè)前后調(diào)度實(shí)現(xiàn)方法 . -7 -2.2.1 進(jìn)程組、會話與終端 .-8 -2.2.2 &、bg、fg 等信號的思想 .-9 -2.2.3 管道.-10 -2.2.4 重定向. -11 -2.3 代碼中相關(guān)結(jié)構(gòu)體及其初始化

9、 .-12 -第三章Mini Shell 的實(shí)現(xiàn).-14 -3.1 方法模塊. -15 -3.1.1 獲取命令函數(shù).-15 -3.1.2 解析命令函數(shù) .-16 -3.1.3 執(zhí)行命令函數(shù) .-18 -3.1.4 判斷后臺作業(yè)函數(shù).-22 -3.1.5 釋放內(nèi)存空間函數(shù) .-23 -3.2 主函數(shù)模塊.-24 -3.2.1 全局變量定義 .-24 -43.2.2 shell 主循環(huán).-24 -3.3 登陸模塊.-24 -3.4 字符界面模塊 . -26 -第四章Mini Shell 的運(yùn)行與測試 .-27 -4.1 簡單命令運(yùn)行與測試 . -27 -4.1.1 用戶登錄界面.-27 -4.1.

10、2 簡單命令演示.-27 -4.2 列表和管道命令運(yùn)行與測試 .-28 -4.3 輸入、輸出重定向命令運(yùn)行與測試 .-29 -總結(jié).-31 -參考文獻(xiàn).-32 -致 謝.-33 -附錄源代碼.-34 -太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-1-Linux Shell 是系統(tǒng)的用戶界面,提供了用戶與內(nèi)核進(jìn)行交互操作的一種接口。它接收 用戶輸入的命令并把它送入內(nèi)核去執(zhí)行。實(shí)際上 Shell 是一個命令解釋器,它解釋由用戶輸入的命令并且把它們送到內(nèi)核。不 僅如此,Shell 有自己的編程語言用于對命令的編輯,它允許用戶編寫由shell 命令組成的程序。Shell 編程語言具有普通編程語言的很多特點(diǎn),

11、比如它也有循環(huán)結(jié)構(gòu)和分支控制結(jié)構(gòu)等,用這種編程語言編寫的 Shell 程序與其他應(yīng)用程序具有同樣的效果。Linux 提供了像 Microsoft Windows 那樣的可視的命令輸入界面-X Window 的圖形用 戶界面(GUI)。它提供了很多窗口管理器,其操作就象Win dows 一樣,有窗口、圖標(biāo)和菜單,所有的管理都是通過鼠標(biāo)控制?,F(xiàn)在比較流行的窗口管理器是 KDE 和 GNOME。而 shell 就實(shí)現(xiàn)了這一點(diǎn),它可以對系統(tǒng)進(jìn)行管理,文件管理,事務(wù)管理等等功能。每個 Linux 系統(tǒng)的用戶可以擁有他自己的用戶界面或Shell,用以滿足他們自己專門的Shell 需要。同 Linux 本身

12、一樣,Shell 也有多種不同的版本。目前主要有下列版本的 Shell:Bourne Shell :是由貝爾實(shí)驗(yàn)室開發(fā)的。BASH :是 GNU 的 Bourne Aga in Shell,是 GNU 操作系統(tǒng)上默認(rèn)的 shell。Korn Shell:是對 Bourne SHell 的發(fā)展,在大部分內(nèi)容上與 Bourne Shell 兼容。C Shell:是 SUN 公司 Shell 的 BSD 版本。作為一名經(jīng)常使用 UNIX/Linux 系統(tǒng)進(jìn)行軟件開的研發(fā)人員,我們對 shell 的功能和趣 味性深有體會。本論文詳細(xì)介紹了 shell 是怎么樣工作和組成的,對 shell 設(shè)計(jì)做一些簡

13、單 的研究。太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-2-第一章 Shell 簡介1.1shell 的定義Shell 是一種特殊的程序,如圖 1.1 所示。他是用戶與 Unix/linux 系統(tǒng) 心臟”(內(nèi)核) 之間的接口。內(nèi)核在系統(tǒng)引導(dǎo)時載入內(nèi)存,管理系統(tǒng)直至關(guān)機(jī)。他創(chuàng)建和控制進(jìn)程,管理 內(nèi)存,文件系統(tǒng)和通信等。內(nèi)核之外的所有其他程序(包括 shell 程序)都保存在磁盤上, 內(nèi)核將這些程序加載到內(nèi)存中運(yùn)行,并在它們終止后清理系統(tǒng)。Shell 是一個工具程序,在用戶登陸后系統(tǒng)啟動。它解釋并運(yùn)行由命令行或腳本文件輸入的命令,從而實(shí)現(xiàn)用戶與內(nèi) 核間的交互。he0stopped 的含義:running

14、Progs= stoppedProgsdone 的含義: runnin gProgs=02.2.3 管道管道相關(guān)知識簡介管道是半雙工的,數(shù)據(jù)只能向一個方向流動;需要雙方通信時,需要建立起兩個管道; 只能用于父子進(jìn)程或者兄弟進(jìn)程之間。 單獨(dú)構(gòu)成一種獨(dú)立的文件系統(tǒng): 管道對于管道兩端 的進(jìn)程而言,就是一個文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門 戶,單獨(dú)構(gòu)成一種文件系統(tǒng),并且只存在與內(nèi)存中。數(shù)據(jù)的讀出和寫入:一個進(jìn)程向管道中寫的內(nèi)容被管道另一端的進(jìn)程讀出。寫入的內(nèi)容每次都添加在管道緩沖區(qū)的末尾,并 且每次都是從緩沖區(qū)的頭部讀出數(shù)據(jù)。利用 Linux 所提供的管道符 川將兩個命令隔

15、開,管道符左邊命令的輸出就會作為管道 符右邊命令的輸入。連續(xù)使用管道意味著第一個命令的輸出會作為第二個命令的輸入,第 二個命令的輸出又會作為第三個命令的輸入,依此類推。管道相關(guān)函數(shù)簡介管道兩端可分別用描述字 fd0以及 fd1來描述,需要注意的是,管道的兩端是固定了 任務(wù)的。即一端只能用于讀,由描述字 fd0表示,稱其為讀端;另一端則只能用于寫,由 描述字 fd1來表示,稱其為寫端。如果試圖從管道寫端讀取數(shù)據(jù),或者向管道讀端寫入數(shù) 據(jù)都將導(dǎo)致錯誤發(fā)太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-13-生。一般文件的 I/O 函數(shù)都可以用于管道,如 close、read write 等等頭文件:#incl

16、ude函數(shù)原型:in t pipe(i nt fd2)函數(shù)傳入值 fd2:管道的兩個文件描述符,之后就是可以直接操作者兩個文件描述符返回值:成功返回 0,失敗返回-1。2.2.4 重定向重定向相關(guān)知識簡介常用 FD 有 3 個,為 0(stdin,標(biāo)準(zhǔn)輸入)、1(stdout,標(biāo)準(zhǔn)輸出)、2(stderr,標(biāo)準(zhǔn)錯 誤) 。用 來改變送出的數(shù) 據(jù)信道 (stdout,stderr),使之輸出到指定的檔案;0 是,?的默認(rèn)值,因此,?與,0?與,1?是一樣的;,?將 stdout 重定向到一個文件.如果文件不存在,那么就創(chuàng) 建它,如果存在,那么就追加到文件后邊。重定向相關(guān)函數(shù)簡介1. dup 函數(shù)

17、簡介:頭文件:#include函數(shù)原形:int dup ( int filedes )功能:返回一個新的描述符,新的描述符是傳給它的描述符的拷貝,由dup 返回的新文描述符一定是當(dāng)前可用文件描述符中的最小數(shù)值。這函數(shù)返回的新文件描述符與 參數(shù)filedes 共享同一個文件數(shù)據(jù)結(jié)構(gòu)。返回值:返回一個新的描述符,若出錯則返回一 1。2. dup2 函數(shù)簡介:頭文件:#includeint dup2( int filedes, i nt filedes2 )功能:函數(shù)返回一個新的文件描述符,與dup 不同的是,dup2 可以用 filedes2 參數(shù)指定新描述符的數(shù)值。如果filedes2 已經(jīng)打開

18、,則先將其關(guān)閉。如若 filedes 等于filedes2 ,則 dup2 返回 filedes2 ,而不關(guān)閉它。同樣,返回的新文件描述符與參數(shù)filedes 共享同一個文件數(shù)據(jù)結(jié)構(gòu)。返回值:函數(shù)返回一個新的文件描述符,若出錯則返回 一 1。太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-14-2.3 代碼中相關(guān)結(jié)構(gòu)體及其初始化redirectio nType 枚舉類型用來選擇重定向時文件描述符打開的模式enum redirect ion TypeREDIRECT_INPUT,REDIRECT_OVERWRITE, REDIRECT_APPEND;redirectio nSpecifier 結(jié)構(gòu)體用來保

19、存重定向時文件及文件描述符的信息,其代碼描述如下:struct redirecti on Specifier enum redirect ion Type type;int fd;char * file name;該結(jié)構(gòu)體中各個元素的說明:redirecti on Type ;重定向的類型fd;被重定向的文件描述符file name;將 fd 重定向到的文件名childProgram 結(jié)構(gòu)體用來保存子進(jìn)程處理、執(zhí)行命令時所需的信息,其代碼描述如下:struct childProgram / 子進(jìn)程pid_t pid;char * argv;int nu mRedirect ions;struc

20、t redirect ion Specifier * redirect ions;glob_t globResult;int freeGlob;int isStopped;該結(jié)構(gòu)體中各個元素的說明:pid;子進(jìn)程 IDargv;保存命令名稱和參數(shù)nu mRedirectio ns;在重定向數(shù)組元素redirecti on Specifier ; I/O 重定向globResult;glob()函數(shù)匹配搜索的結(jié)果freeGlob;保存 globfree(&globResult)的返回值isStopped 標(biāo)識命令是否在執(zhí)行job 結(jié)構(gòu)體用來保存作業(yè)隊(duì)列中的作業(yè)信息,其代碼描述如下:struct

21、job int jobId;int nu mProgs;int runnin gProgs;char * text;太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-15-char * cmdBuf;pid_t pgrp;struct childProgram * progs;struct job * n ext;int stoppedProgs;該結(jié)構(gòu)體中各個元素的說明:jobId :作業(yè)號numProgs:作業(yè)中的進(jìn)程數(shù)runnin gProgs:作業(yè)中運(yùn)行的進(jìn)程數(shù)(包括處于stoped 狀態(tài)的)Text :儲存命令頭,女口 ps -l 中的 pscmdBuf :存整個命令,如 ps ClPgrp:進(jìn)

22、程組 idchildProgram :進(jìn)程定義Next :指向下一個作業(yè)Stopped Progs 說明作業(yè)是否處于停止?fàn)顟B(tài),(jobs, fg, bg)jobset 結(jié)構(gòu)體用于作業(yè)隊(duì)列的存儲,其代碼描述如下:struct jobSetstruct job * head;struct job * fg;該結(jié)構(gòu)體中各個元素的說明:head:用來表示作業(yè)鏈表的頭節(jié)點(diǎn)fg :用來存儲在前臺執(zhí)行的作業(yè)作業(yè)及前后臺調(diào)度由代碼的實(shí)現(xiàn)如圖2.6。圖 2.6 作業(yè)以及前后臺調(diào)度實(shí)現(xiàn)方法太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-16-第三章 Mini Shell 的實(shí)現(xiàn)Mini shell 分為四個模塊:主函數(shù)模塊

23、:程序入口 main 函數(shù)、全局變量的初始化、Shell 主循環(huán)。方法模塊:命令的獲取、解析、執(zhí)行、后臺作業(yè)的狀態(tài)的檢測以及完成命令后內(nèi)存空間的釋放。登陸模塊:用于 MiniShell 啟動后的登陸。字符界面模塊:用于登陸成功后顯示字符歡迎界面。各個模塊中的功能函數(shù)如圖 3.1 所示:圖 3.1 各個模塊所實(shí)現(xiàn)的功能3.1 方法模塊方法模塊是 Mini shell 實(shí)現(xiàn)的核心模塊,對應(yīng)程序中的 method.c 文件。該模塊中實(shí)現(xiàn) 了獲取、解析、執(zhí)行三大基本功能外,還實(shí)現(xiàn)了后臺作業(yè)狀態(tài)監(jiān)測功能以及內(nèi)存空間釋放 功能。3.1.1 獲取命令函數(shù)太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-17-獲取命令函

24、數(shù)在程序中的函數(shù)名為 getComma nd 函數(shù)。函數(shù)名:getComma nd功能:輸入的一列命令,作為字符串處理,讓fget 函數(shù)讀取到這一系列的字符串參數(shù):char* comma nd 用來保存獲取到的命令字符串返回值:int 型成功返回 0;失敗返回 1其程序流程圖如下圖 3.2 所示:圖 3.2 獲取命令流程圖getComma nd 函數(shù)中所使用的獲取函數(shù) fgets()簡介:函數(shù)名:fgets用 法:char *fgets(char *string, int n, FILE *stream);返回值:成功則返回 sting 字符串指針,失敗返回 NULL功能:輸入的一系列命令,作

25、為字符串處理,讓fget 函數(shù)讀取到這一系列的字符串。存放到 fget 函數(shù)中的 str 函數(shù)。例如:#i nclude void mai n()太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-18-char *cmd=(void *)malloc(256*sizeof(char);for(i=0;i255;i+)cmdi=0;fgets(cmd,256,std in);printf(“s ,cmd);3.1.2 解析命令函數(shù)解析函數(shù)在程序中的函數(shù)名為 parseComma nd函數(shù)名:parseCommand功能:忽略命令前的空格忽略空命令和以#開頭的命令初始化后臺標(biāo)志和 job 結(jié)構(gòu)體及其內(nèi)部的 p

26、rog 結(jié)構(gòu)體將輸入的字符串通過 glob 函數(shù)匹配路徑并將匹配的路徑,以字符串的形式保 存到prog 結(jié)構(gòu)體中的 argv數(shù)組中參數(shù):char * commandPtr 傳入指向獲取的命令字符串首地址的指針;Struct job* job 用來存放解析出來的命令;int * isBg用來標(biāo)識命令是否后臺執(zhí)行,0 為前臺;1 為后臺(int*用來直接修改傳入的參數(shù)的值)。返回值:int 型,成功返回 0,失敗返回 1。解析函數(shù)在解析命令時需要識別各個字符以及它所代表的命令含義,如?&?為后臺執(zhí)行;?|為管道;?? ?為特殊字符等等。圖 3.3 為解析函數(shù)對部分字符的處理。太原科技大學(xué)華科學(xué)院畢

27、業(yè)設(shè)計(jì)(論文)-19-Shell 中一條命令的格式大致為:命令參數(shù) 1參數(shù) 2.;由此可看出命令與參數(shù)、參數(shù)與參數(shù)之間都是以空格加以分辨、 區(qū)分的, 所以解析函數(shù)在忽略掉命令字符串開頭的 空格后,在字符串中再次遇到空格就說明代表一條命令的字符串或者是命令操作的參數(shù)已 結(jié)束;空格之后的字符串是代表另一個參數(shù)或命令的字符串了。由此就可以獲取到命令字 符中的單獨(dú)的一個詞,再通過 glob()函數(shù)匹配出該詞的路徑,并保存到結(jié)構(gòu)體中。圖 3.3 解析函數(shù)對部分特殊字符的處理glob ()函數(shù)介紹頭文件:#include 函數(shù):int glob( const char *pattern, int flag

28、s, int (*errfunc)(const char *epath, int eerrno),glob_t *pglob);釋放內(nèi)存函數(shù):void globfree( glob_t *pglob);glob_t 結(jié)構(gòu)體用來保存匹配搜索的結(jié)果:typedef struct太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-20-in t gl_pathc;匹配已知模式串的文件名個數(shù)char *gl_pathv;匹配模式串的文件名數(shù)組int gl_offs;glob_t;glob_t 使用完成后必須通過 globfree()函數(shù)釋放內(nèi)存3.1.3 執(zhí)行命令函數(shù)執(zhí)行命令函數(shù)在程序中的函數(shù)名為run Comma

29、 nd函數(shù)名:run Comma nd功能:1.判斷所執(zhí)行的命令是否為實(shí)現(xiàn)的內(nèi)部命令exit、pwd、cd、jobs、fg/bg ;如果執(zhí)行的是內(nèi)部命令則直接執(zhí)行程序內(nèi)實(shí)現(xiàn)的內(nèi)部命令;2.執(zhí)行外部命令時可通過解析命令函數(shù)的判定含有代表重定向、管道、后臺執(zhí) 行字符的命令的標(biāo)識執(zhí)行相應(yīng)的操作。參數(shù):Job 結(jié)構(gòu)體類型jobSet 結(jié)構(gòu)體類型的 job 鏈表inBg 標(biāo)識是否后臺執(zhí)行命令返回值:int 型,成功返回 0,失敗返回 1。執(zhí)行函數(shù)中實(shí)現(xiàn)的內(nèi)部命令有:exit、pwd、cd、fg、bg、jobs。exit 用于退出 Mini Shell,用 exit ()函數(shù)實(shí)現(xiàn)pwd 顯示當(dāng)前目錄,用

30、getcwd ()函數(shù)實(shí)現(xiàn)cd 用于切換目錄,用 chdir ()函數(shù)實(shí)現(xiàn)bg/fg 用于后臺的暫停作業(yè)繼續(xù)執(zhí)行,用kill()函數(shù)發(fā)出 SIGCONT 信號實(shí)現(xiàn)jobs 用于判斷作業(yè)狀態(tài)并打印狀態(tài)。pwd 命令的實(shí)現(xiàn)所使用的函數(shù):1.getcwd ()函數(shù)函數(shù)名:char *getcwd(char *buf, i nt size);太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-21-功能:會將當(dāng)前工作目錄的絕對路徑復(fù)制到參數(shù)buf 所指的內(nèi)存空間中,參數(shù) size 為buf 的空間大小。返回值:返回自動配置的字符串指針;失敗返回 NULL。此函數(shù)是 pwd 命令的實(shí)現(xiàn),調(diào)用此函數(shù)即可。cd 命令的實(shí)

31、現(xiàn)所使用的函數(shù):1. chdir ()函數(shù):函數(shù)名:int chdir(c onst char *path name);返回值:0 成功,1 錯誤功能:改變工作目錄2. getenv ()函數(shù):函數(shù)名: char * gete nv (char *env var)功能:用來獲取參數(shù) en war 的環(huán)境變量的內(nèi)容,返回值:成功返回指向該內(nèi)容的指針,失敗返回NULLcd 命令后面的參數(shù)傳入函數(shù) chdir ()中執(zhí)行,這樣就達(dá)到了 cd 改變工作目錄的效果; 當(dāng) cd命令后面沒有參數(shù)時,可以令 path name 賦予一個恒定的路徑名-HOME。這就需要使 用 getenv()函數(shù)來獲取 hom

32、e 的環(huán)境變量。jobs 命令的實(shí)現(xiàn):jobs 命令通過遍歷作業(yè)鏈表,通過比較每一個作業(yè)的所有進(jìn)程的正在運(yùn)行個數(shù)與停止 個數(shù),來判定該進(jìn)程是停止還是運(yùn)行的狀態(tài)并將其狀態(tài)打印出來。其執(zhí)行流程圖如圖34太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-22-圖 3.4 jobs 命令流程圖fg/bg 命令的實(shí)現(xiàn):fg/bg 命令的作用都是使后臺暫停的作業(yè)繼續(xù)執(zhí)行-給對應(yīng)的作業(yè)發(fā)送 SIGCONT 信號。其中倆個命令的區(qū)別為:fg 命令會將作業(yè)從后臺移動到前臺,而bg 命令仍讓作業(yè)繼續(xù)在后臺執(zhí)行。fg/bg 命令流程圖如圖 3.5。給指定進(jìn)程發(fā)送信號需要用到 kill ()函數(shù)。kill ()函數(shù)函數(shù)名:int

33、 kill(pid_t pid,int sig);函數(shù)說明:可以用來發(fā)送參數(shù)sig 指定的信號給參數(shù) pid 指定的進(jìn)程。sig 可選擇的信號名見下表:表 3.1 Kill 發(fā)送參數(shù)相對應(yīng)的信號名1. SIGHUP2 . SIGINT3. SIGQUIT4. SIGILL5. SIGTRAP6. SIGABRT7. SIGBUS8. SIGFPE9. SIGKILL10 . SIGUSR111 . SIGSEGV12. SIGUSR213. SIGPIPE14. SIGALRM15. SIGTERM16. SIGSTKFLT17. SIGCHLD18 . SIGCONT19 . SIGSTOP

34、20. SIGTSTP21 . SIGTTIN22. SIGTTOU23. SIGURG24. SIGXCPU太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-23-圖 3.5 fg/bg 命令流程圖當(dāng)執(zhí)行函數(shù)要執(zhí)行命令時,首先要判斷即將執(zhí)行的命令是否為內(nèi)部命令,此時需要用 到strcmp ()函數(shù)來比較將要執(zhí)行的命令是否與實(shí)現(xiàn)的內(nèi)部命令相同。strcmp ()函數(shù)函數(shù)名:int strcmp(char *s1,char * s2);功能:比較字符串 si 和 s2。這個函數(shù)解決了識別命令的問題,當(dāng)輸入的命令字符串與函數(shù)中參數(shù)的字符串相同時, 用 if判斷得到的返回值,調(diào)用后面的代碼,實(shí)現(xiàn)相關(guān)的命令。圖

35、3.6 為執(zhí)行命令函數(shù)的流程圖:太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-24-圖 3.6 執(zhí)行命令函數(shù)流程圖當(dāng)執(zhí)行的命令時外部命令時,需要調(diào)用執(zhí)行其他的程序的可執(zhí)行文件,此時就要用到 exec函數(shù)族中的函數(shù)。execv 函數(shù)族(執(zhí)行文件)包括以下幾種:execl, execv,execle, execve, execlp, execvp頭文件:#includevunistd.h函數(shù)名:int execvp(c onst char *file ,char * const argv );函數(shù)說明:execvp()會從 PATH 環(huán)境變量所指的目錄中查找符合參數(shù)file 的文件名,找到后便執(zhí)行該文件,

36、然后將第二個參數(shù)argv 傳給該欲執(zhí)行的文件。返回值:執(zhí)行成功則函數(shù)不會返回,執(zhí)行失敗則直接返回-1,失敗原因存于 errno 中。3.1.4 判斷后臺作業(yè)函數(shù)判斷后臺作業(yè)函數(shù)在程序中的函數(shù)名為checkJobs太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-25-函數(shù)名:checkJobs功能:檢測后臺所有的指令是否執(zhí)行完成,將其狀態(tài)打印出來參數(shù):jobSet 結(jié)構(gòu)體指針輸入待檢測的指令鏈表返回值:無函數(shù)在等待子進(jìn)程結(jié)束時,用到了 waitpid ()函數(shù)以及該函數(shù)的一些宏。函數(shù)名:pid_t waitpid(pid_t pid,i nt * status,i nt opti on s);功 能: w

37、aitpid()會暫時停止目前進(jìn)程的執(zhí)行,直到有信號來到或子進(jìn)程結(jié)束。如果在 調(diào)用wait()時子進(jìn)程已經(jīng)結(jié)束,則 wait()會立即返回子進(jìn)程結(jié)束狀態(tài)值。子進(jìn)程的結(jié)束狀態(tài)值會由參數(shù) status 返回,而子進(jìn)程的進(jìn)程識別碼也會一起返回返回值:如果執(zhí)行成功則返回子進(jìn)程識別碼(PID),如果有錯誤發(fā)生則返回-1。失敗原因 存于errno 中。如果不在意結(jié)束狀態(tài)值,則參數(shù) option 可以為 0 或下面模式的 或”的組合:WNOHANG 如果沒有任何已經(jīng)結(jié)束的子進(jìn)程則馬上返回,不予以等待。 WUNTRACED 如果子進(jìn)程進(jìn)入暫停執(zhí)行情況則馬上返回,但結(jié)束狀態(tài)不予以理會。子進(jìn)程的結(jié)束狀態(tài)返回后存于

38、 status 下面的幾個宏可判斷其結(jié)束情況:WIFEXITED(status):判斷是否正常結(jié)束才能使用此宏,若子進(jìn)程正常結(jié)束則為非0。WEXITSTATUS(status):取得子進(jìn)程 exit()返回的結(jié)束代碼,WIFSIGNALED(status):如果子進(jìn)程是因?yàn)樾盘柖Y(jié)束則此宏值為真WTERMSIG(status):取得子進(jìn)程因信號而中止的信號代碼,WIFSIGNALED 來判斷后 才使用此宏。WIFSTOPPED(status):如果子進(jìn)程處于暫停執(zhí)行情況則此宏值為真。一般只有使用WUNTRACED 時才會有此情況。太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-26-圖 3.7 為判斷后

39、臺作業(yè)狀態(tài)流程圖:圖 3.7 判斷后臺作業(yè)狀態(tài)流程圖3.1.5 釋放內(nèi)存空間函數(shù)釋放內(nèi)存空間函數(shù)在程序中的函數(shù)名為freeJob函數(shù)名:freeJob功能:釋放分配給 job 結(jié)構(gòu)體各個成員的空間參數(shù):struct job *cmd job 結(jié)構(gòu)體類型的指針返回值:無當(dāng)命令執(zhí)行完成后,為其分配的存放命令字符串、以及建立作業(yè)的指針空間就已經(jīng)無 用了,這些空間都應(yīng)當(dāng)釋放掉,以便其他進(jìn)程使用。其流程圖如圖 3.8 所示:太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-27-圖 3.8 釋放內(nèi)存函數(shù)流程圖3.2 主函數(shù)模塊主函數(shù)模塊是整個 Mi ni shell 程序的入口,對應(yīng)程序中的 ma in .c 文件

40、。申明了各個全 局變量以及 shell 的主循環(huán)。3.2.1 全局變量定義char comma ndMAX_COMMAND_LEN + 1;/用于獲取命令字符串后的保存char * nextCommand = NULL;/用于多命令的情況struct jobSet jobList = NULL, NULL ;/用于會話struct job newJob;/用于作業(yè)(進(jìn)程組)newJob. nu mProgs=0;記錄作業(yè)的進(jìn)程數(shù)int inBg=0;用于后臺標(biāo)志int i;int status;/用于作業(yè)的狀態(tài),在 job,fg,bg 時候使用3.2.2 shell 主循環(huán)Shell 主循環(huán)是

41、一個死循環(huán),循環(huán)內(nèi)調(diào)用方法模塊中實(shí)現(xiàn)的功能函數(shù)來實(shí)現(xiàn)shell 功能:獲取命令函數(shù)阻塞函數(shù)用于等待命令輸入;解析命令用來對獲取的命令字符串進(jìn)行預(yù)處 理;執(zhí)行命令函數(shù)用于執(zhí)行處理過的命令。其流程圖如圖3.9 所示。3.3 登陸模塊登陸模塊對應(yīng)程序中的 login.c 文件。在運(yùn)行程序后會提示用戶輸入用戶名和密碼,輸 入正確的用戶名和密碼以后才可以登陸程序。如果三次輸入用戶名或密碼不正確則退出程 序。其流程圖如圖 3.10 所示。太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-28-圖 3.9 shell 主循環(huán)流程圖太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-29-圖 3.10 登陸模塊流程圖3.4 字符界面模

42、塊字符界面對應(yīng)于程序的 welcome.c 文件。用于程序成功登陸后,輸出顯示字符界面 因只是輸出字符,所以不再詳細(xì)介紹。太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-30-第四章 Mini Shell 的運(yùn)行與測試4.1 簡單命令運(yùn)行與測試4.1.1 用戶登錄界面程序編譯成功以后用戶在終端中輸入./mimishell 程序會提示用戶輸入用戶名和密碼,輸入正確的用戶名和密碼以后才可以登陸程序。本程序默認(rèn)的用戶名和密碼為: wj/123456。用戶三次輸入密碼不正確則退出程序。r_1x - wjwj-ubuntu: T虞面/MlnfShell用戶名:j密碼:鎬入亦密碼或用戶名錯誤! 請重新輸人.用戶名:

43、wj密碼:宜錄應(yīng)功2014-Apr-3e Ned 54/30/14 +0S00MtnlShelL$圖 4.1 用戶登錄演示4.1.2 簡單命令演示使用 Is 命令就可以顯示你的當(dāng)前目錄的內(nèi)容。Is 命令有許多可用的選項(xiàng)。要看到 Is 命令的所有選項(xiàng),下面是一個與 Is 一起使用的一些常用選項(xiàng)的簡短列表。-a 全部(all)。列舉目錄中的全部文件,包括隱藏文件(.file name)。位于這個列 表的起首處的.和.依次是指父目錄和你的當(dāng)前目錄。稱明間書名說時作目目始Minx Shell一個滬型5h亡ll2014-4-1MJ太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-31-l 長(Iong)。列舉目錄內(nèi)

44、容的細(xì)節(jié),包括權(quán)限(模式)、所有者、組群、大小、 創(chuàng)建日期、文件是否是到系統(tǒng)其它地方的鏈接,以及鏈接的指向。-F 文件類型(File type)。在每一個列舉項(xiàng)目之后添加一個符號。這些符號包括: /表明是一個目錄;表明是到其它文件的符號鏈接;*表明是一個可執(zhí)行文件。-r 逆向(reverse。從后向前地列舉目錄中的內(nèi)容。-R 遞歸(recursive)。該選項(xiàng)遞歸地列舉所有目錄(在當(dāng)前目錄之下)的內(nèi)容。-S 大小(size)。按文件大小排序如圖 4.2 所示,測試其中一種用法,達(dá)到預(yù)期效果。cd 命令來改變工作目錄。圖 4.2 中,切換到根目錄下。pwd 命令代表“print working

45、directory (打印工作目錄)。當(dāng)你鍵入 pwd 時,你是在 請你的 Linux 系統(tǒng)顯示你的當(dāng)前位置。圖 4.2 所表明你當(dāng)前正處在/目錄中,也就是根目錄 中。在上步cd 命令實(shí)現(xiàn)的。.一口MtntshellJ Is bln Include Include,h* Makefile MtntShellMintShellS圖 4.2 簡單命令解析演示4.2 列表和管道命令運(yùn)行與測試Linux 列表命令很簡單,就是一串命令之間用分號隔開,分別先后執(zhí)行輸入的命令。管道命令:利用 Linux 所提供的管道符“將兩個命令隔開,管道符左邊命令的輸出就會作 為管道符右邊命令的輸入。連續(xù)使用管道意味著第

46、一個命令的輸出會作為第二個命令的輸obj readme readmeETCcd /pwdMiniShellSMiniShellS/honc/wjMinishell$四月613202714212818152229cal 2914五4111825三四239 ie16 1724121926MtntShell$ Is -I總用量131Z8-rw-rw-r- 1 wj-rwxrw-rw- 1 wj-rwxrw-rw- 1 wj”叭1 wi7680577126412697603445月月月月16121228201320132013a * txt cscope15,Ba ”tar5 7+tarexanpl.

47、es, desktop太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-32-入,第二個命令的輸出又會作為第三個命令的輸入,依此類推。如圖4.3 所示,第一個命令的輸出所有用戶的信息作為第二個命令的輸入來源。篩選出的用戶信息。 -口wjiwj-ubuntu:吋虞面/MinlShellHtniShellS Is;pwda.txtexamples.desktop qtworkspacecscope- 15*88Htar ncurses*targz qtsdk-2O10+O5安裝步驟ctags-547, tar omni* tarvinrc處共的/home/wjMintshellS cat /etc/passw

48、d | grep wjwj:x;1000:1000:wj,/hame/wj;/bin/bashMinlShell$ cal;data四月2014日一二三四五六12345678 91611 1211 1415 161718 192e 2122 232425 2627 2& 29 EE exec() af data failed: No such file or dtrECtory MiniShell$ date貫14年34月3日 星期三15:32:26 CSTHintshelis |圖 4.3 命令列表、管道演4.3 輸入、輸出重定向命令運(yùn)行與測試在 Linux 命令行模式中,如果命令所需的輸出

49、不是來自鍵盤,而是來自指定的文件, 這就是輸入重定向。同理,命令的輸出也可以不顯示在屏幕上,而是寫入到指定文件中, 這就是輸出重定向。每個命令都使用標(biāo)準(zhǔn)輸入流、標(biāo)準(zhǔn)輸出流。這些標(biāo)準(zhǔn)流被預(yù)告分配給鍵盤和顯示器。在需要的時候,可以使用重定向臨時改變這些默認(rèn)分配。重定向是這樣的一種過程。我所 實(shí)現(xiàn)的shell 輸入重定向,運(yùn)算符為小于號或兩個小于號(或)。將它看作是指向命令的一個箭頭,意味著這個命令從此給派的文件得到它的輸入,借助描述符0 將應(yīng)用于標(biāo)準(zhǔn)輸入,由于只存在一種標(biāo)準(zhǔn)輸入,所以我在實(shí)現(xiàn)這個功能的時候,省略掉了。設(shè)計(jì)重定向 的還有一個就是輸出重定向,運(yùn)算符為大于號或兩個大于號(或 ),可以將大

50、于號看作是從命令外指的一個箭頭,并且指向一個接收輸出的文件。使用哪個運(yùn)算符取決于想要 如何處理輸出文件,如果只想看到該命令的本次運(yùn)行的輸出,可以使用一個大于號(),面桌檔載樂文下昔板頻片模視圉太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-33-如果想要覆蓋并用新輸出替換當(dāng)前文件,則必須使用一個大于號(),想追加則用兩個大于號( )。本測試只使用其中一部分功能。如圖 4.4 和圖 4.5太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-34-x - wj)wj-ubuntu: /Affi/MiniShelLMtntShell nkdtr testMintShellS cd testHinlShelLS IsMini

51、Shell$ date aMintshellS 15;cat a2日1斗年 吐4月300星期三15:44:00 CSTMlntSheLl$cal bMintsheYl$calwj-ubuntu:面/WniSh芒11圖 4.5 作業(yè)管理MintShell$ sleep 46&1 8938MvniShell$1 RunningMiniShell$ PIOTTY7754 pts/O 8014ptS/O 303Spts/O8039ptS/DHintShells psPIO TTY7754 pts/O 8014pts/O B03Spts/O8040pts/OrnntSheflS psPID TTY775

52、4 pts/O8014 pts/O 8038ptS/0 804t pts/O1 DonejobsTIME as:oa:Go00:09:00O0:09:0000:03:00TIME09:00:0000:60:0009:69:0000:03:00TIME oe:oo:OG00:O0:sleep 4箭CMO bash mtnishellsleepP客CMD bash ntnishellsleep pwCMD bash ninishellsleep sleep 408太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-35-總結(jié)畢業(yè)設(shè)計(jì)是我在大學(xué)學(xué)習(xí)階段的最后一個環(huán)節(jié),是對所學(xué)基礎(chǔ)知識和專業(yè)知識的一種 綜合應(yīng)用,是

53、一種綜合的再學(xué)習(xí)、再提高的過程,這一過程有助于培養(yǎng)我的學(xué)習(xí)能力和獨(dú) 立工作能力。我的題目是 shell 的設(shè)計(jì)與實(shí)現(xiàn),這個題目對于我而言是一個全新的挑戰(zhàn)。在設(shè)計(jì)時, 要求對 Linux 系統(tǒng)有一定的了解,包括 Linux 系統(tǒng)中的內(nèi)核函數(shù),進(jìn)程間通信,文件的操 作,標(biāo)準(zhǔn) I/O庫,shell 的原理等等。知識面廣是學(xué)習(xí)中存在的困難問題,我也不例外。我 選擇這個題目,就是想在大學(xué)這個最后的、最重要的時間里,自己學(xué)到東西加上自己的理 解去做一個 Linux 系統(tǒng)中的 shell,創(chuàng)造出屬于自己的 Linux 窗口命令,不在局限于系統(tǒng)的 命令,也許在將來的某一天,系統(tǒng)的命令都是用中文輸入,不懂英語的

54、人也會用 shell 命令 來操作系統(tǒng),所以借此次機(jī)會,我要把我的畢業(yè)設(shè)計(jì)做好,離開我的美好的大學(xué)。雖然在畢業(yè)設(shè)計(jì)的過程中存在不足之處,沒有 Linux 系統(tǒng)中自帶 shell 那么全面,比如強(qiáng)大的 tab 鍵補(bǔ)全功能、按上下鍵翻看歷史命令等,此次設(shè)計(jì)沒有達(dá)到這樣的效果,諸如 次類的問題還是很多。原因之一是這些功能不在本次設(shè)計(jì)的目的之內(nèi),其二是我沒有足夠 的經(jīng)歷來完成這些功能。在設(shè)計(jì)的過程中,困難不斷,但通過自己不斷的查閱書籍和導(dǎo)師 的悉心指導(dǎo),最后所有困難都迎刃而解。這對于培養(yǎng)我們的自學(xué)能力和獨(dú)立工作能力是非 常有幫助的。通過本次畢業(yè)設(shè)計(jì),我感到自己應(yīng)用基礎(chǔ)知識及專業(yè)知識解決問題的能力有了很

55、大的 提高,并且這次畢業(yè)設(shè)計(jì)的選題,是一個實(shí)際東西,因此,是在我即將工作之前,它是一 次重要演練。我想,通過這次畢業(yè)設(shè)計(jì),到了工作單位后,我將能夠更快的適應(yīng)工作崗位 和工作要求。我對自己充滿信心??傊@次畢業(yè)設(shè)計(jì)對我來說,收獲不少,學(xué)習(xí)了很多,受益匪淺。太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-36-參考文獻(xiàn)1(美)Kenneth A.Reek 著.徐波 譯.C 和指針M.北京:人民郵件出版社,2008.2(美)拉芙 著陳莉君 譯.Lin ux 內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)M.北京:機(jī)械工業(yè)出版社,2011.6975.3(美)理查德 史蒂文斯,(美)拉戈 著.尤晉元,張亞英,戚正偉等 譯.UNIX 環(huán)境高級編

56、程M.北京:人民郵電出版社,2006.171192.4韋東山著.嵌入式 Linux 應(yīng)用開發(fā)完全手冊M.北京:機(jī)械工業(yè)出版社,2008.何明,何茜穎等著.Linux 培訓(xùn)教程M.北京:清華大學(xué)出版社,2010.(英)馬修,(英)斯通斯著.陳健譯.Linux 程序設(shè)計(jì)M.北京:人民郵電出版社,2010.214220.7(美)博韋,西斯特 著.陳莉君 譯.深入理解 LINUX 內(nèi)核M.北京沖國電力出版社,2001.8(美CHRISTOPHER VICKERY著.李祥凱 譯.實(shí)踐大師:unix shell 編程篇M.北京:電子工業(yè)出版社,2000.9(美)索貝爾 著,楊明軍 譯.Linux 命令/編

57、輯器與 Shell 編程M.北京:清華大學(xué)出版社,2007.10 孟慶昌 著.Linux 基礎(chǔ)教程M.北京:電子工業(yè)出版社,2007.11 (美)佛努丹,(美)吉爾伯格 著.彭松虎 譯.UNIX 和 Shell 程序設(shè)計(jì)權(quán)威教程.北京:清華大學(xué)出版社,2003.12 (美)博韋,西斯特 著.陳莉君 譯.深入理解 LINUX 內(nèi)核M.北京沖國電力出版社,2001.13 (英)馬修,(英)斯通斯著.陳健譯.Linux 程序設(shè)計(jì)M.北京:人民郵電出版社,2010.14 Richand F.Gabang 著.UNIX 和 Shell 程序設(shè)計(jì)權(quán)威教程.北京:清華大學(xué)出版社,2002.15 (美)拉芙

58、著.陳莉君 譯.Linux 內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)M.北京:機(jī)械工業(yè)出版社,2011.太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-37-致謝在畢業(yè)設(shè)計(jì)完成之際,我真心地感謝在設(shè)計(jì)之中給予我?guī)椭慕芷盏耐跤鹄蠋?。在這 幾個月中,太多的人給予了我鼓勵和耐心的指導(dǎo),王羽老師勤奮嚴(yán)謹(jǐn)?shù)闹螌W(xué)作風(fēng)、淵博的 專業(yè)知識和孜孜不倦的教學(xué)精神對我產(chǎn)生了很大的影響,我相信這精神會使我受益終生。同時要感謝互聯(lián)網(wǎng)上的許多技術(shù)前輩們, CSDN 論壇 C 語言版和 Linux 版,百度百科 中維護(hù)資料的各位網(wǎng)友以及開源社區(qū)的許多無名前輩,是你們默默無聞的奉獻(xiàn)精神,以及 對編程無比的熱情,激勵著我一步步向前走。在有限的時間內(nèi)盡可能多的掌

59、握了更多的技 術(shù)知識,在分享了技術(shù)前輩們的編程成果的同時,也提高了自己的編程能力,并以自己的 源碼回報(bào)廣大互聯(lián)網(wǎng)上熱衷編程的人們。最后衷心的祝愿你們身體健康,工作順利!此致敬禮太原科技大學(xué)華科學(xué)院畢業(yè)設(shè)計(jì)(論文)-38-附錄源代碼method.c 文件中的部分代碼如下:#in elude method.hint getComma nd(char * comma nd) prin tf(Mi ni Shell$ );if (!fgets(comma nd, MAX_COMMAND_LEN, stdi n) return 1;comma ndstrle n( comma nd) - 1 = 0:r

60、eturn 0;int parseComma nd(char * comma ndPtr, struct job * job, int * isBg) char * comma nd;char * retur nComma nd = NULL;char * src, * buf, * chptr;int argc = 0;int done = 0;int argvAlloced;int i;char quote = 0;int count;struct childProgram * prog;while (*comma ndPtr & isspace(*comma ndPtr)/用來忽略字符串

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論