版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 本科畢業(yè)設計(論文)</p><p><b> (二零 屆)</b></p><p> Linux Shell的 研 究 與 開 發(fā)</p><p> 所在學院 </p><p> 專業(yè)班級 計算機科學與技術 &
2、lt;/p><p> 學生姓名 學號 </p><p> 指導教師 職稱 </p><p> 完成日期 年 月 </p><p> 摘要:介紹了在Linux系統(tǒng)背景下對Shell相關知識的了解,編寫簡單的she
3、ll命令例如ls,cp,cat和rm命令等并且介紹了Shell相關的外部程序命令及管道和輸入輸出重定向功能,以加深對Shell這方面知識的理解,為此類程序的開發(fā)提供一定的啟示性和指導性。熟悉Linux操作系統(tǒng)下的C語言高級編程,了解Linux操作系統(tǒng)的shell執(zhí)行方式,熟練運用C語言對字符串進行處理。學習并掌握Linux C語言系統(tǒng)庫函數的用法,熟練運用某些庫函數來完成設計。</p><p> 在Linux
4、系統(tǒng)中,Shell是最常使用的程序,其主要作用是偵聽用戶指令,啟動指令所指定的進程并將結果返回給用戶。Linux系統(tǒng)中的shell,除了可作為命令編譯器之外,它也是一種不錯的編程語言,是系統(tǒng)管理維護時的重要工具。</p><p> 關鍵詞:linux;shell命令;管道;輸入輸出重定向</p><p> Research and development of Linux
5、160;shell</p><p> Abstract:Linux systems are introduced in the context of knowledge about Shell, write a simple shell command such as ls, cp, cat, and rmcommands and introduced the Shell commands and e
6、xternal programs related to pipeline and input and output redirection. in order to deepen Shell knowledge and understanding in this area for the development of such procedures provide some inspiration and guidance. Fa
7、miliar with the Linux operating system under the C high-level programming language,understan</p><p> Keywords: Linux;shell command;pipeline; input and output redirection</p><p><b> 目錄<
8、;/b></p><p><b> 1 緒論1</b></p><p> 1.1 課題的研究背景1</p><p> 1.1.1 shell簡介1</p><p> 1.1.2 shell 的發(fā)展過程1</p><p> 1.2 課題研究的目的與意義3</
9、p><p> 1.3 課題的研究內容3</p><p> 2 linux下shell的開發(fā)方法6</p><p> 2.1 c語言簡介6</p><p> 2.2 c 語言的結構特點:6</p><p> 2.3 c 語言的優(yōu)點6</p><p> 2.4 c語言缺
10、點7</p><p> 2.5 shell概念8</p><p> 2.6 shell語言9</p><p> 3 開發(fā)工具和開發(fā)環(huán)境介紹12</p><p> 3.1 gcc 簡介12</p><p> 3.2 gcc的基本用法和選項13</p><p> 4
11、 基本功能和實現方法17</p><p> 5 主要源代碼介紹18</p><p> 5.1 ls功能18</p><p> 5.2 cp功能22</p><p> 5.3 who 功能23</p><p> 5.4 cat 功能25</p><p> 5.5 r m
12、 功能27</p><p> 5.6 全部功能集合my_cmd30</p><p> 6 總結及展望41</p><p> 致 謝錯誤!未定義書簽。</p><p><b> 參考文獻41</b></p><p><b> 1 緒論</b></
13、p><p> 1.1 課題的研究背景</p><p> 1.1.1 shell簡介</p><p> Shell是一種具備特殊功能的程序, 它是介于使用者和 UNIX/Linux 操作系統(tǒng)之核心程序(kernel)間的一個接口。</p><p> 為了對用戶屏蔽內核的復雜性,也為了保護內核以免用戶誤操作造成損害,在內核的周圍建了一個外
14、殼(shell)。用戶向shell提出請求,shell解釋并將請求傳給內核。 </p><p> 使用較廣的shell有標準的Bourne shell (sh)、Korn Shell(ksh)、C shell (csh)、Bourne Again Shell(bash)等。</p><p> shell的另一個重要特性是它自身就是一個解釋型的程序
15、設計語言,shell程序設計語言支持絕大多數在高級語言中能見到的程序元素,如函數、變量和程序控制結構。shell編程語言簡單易學,任何在提示符中能鍵入的命令都能放到一個可執(zhí)行的shell程序中。</p><p> 本質上,shell 腳本是命令行命令簡單的組合到一個文件里面。Shell基本上是一個命令解釋器,類似于DOS下的command.com。它接收用戶命令,然后調用相應的應用程序[1]。<
16、/p><p> 管道是Linux 支持的最初Unix IPC形式之一,具有以下特點: </p><p> 管道是半雙工的,數據只能向一個方向流動;需要雙方通信時,需要建立起兩個管道; 只能用于父子進程或者兄弟進程之間(具有親緣關系的進程); 單獨構成一種獨立的文件系統(tǒng):管道對于管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門戶,單獨構成一種文件系統(tǒng),并
17、且只存在于內存中。一個進程向管道中寫的內容被管道另一端的進程讀出,寫入的內容每次都添加在管道緩沖區(qū)的末尾,并且每次都是從緩沖區(qū)的頭部讀出數據。</p><p> 執(zhí)行一個shell命令行時通常會自動打開三個標準文件,即標準輸入文件(stdin),通常對應終端的鍵盤;標準輸出文件(stdout)和標準錯誤輸出文件(stderr),這兩個文件都對應終端的屏幕。進程將從標準輸入文件中得到輸入數據,將正常輸出數據輸出到
18、標準輸出文件,而將錯誤信息送到標準錯誤文件中。</p><p> 1.1.2 shell 的發(fā)展過程</p><p> 標準的 UNIX shell 是V7(AT&T的第七版)UNIX,在1979 年底被提出,且以它的創(chuàng)造者 Stephen Bourne 來命名。Bourne shell 是以 Algol 這種語言為基礎來設計,主要被用來做自動化系統(tǒng)管理工作。雖然 Bourn
19、e shell 以簡單和速度而受歡迎,但它缺少許多交談性使用的特色,例如歷程、別名和作業(yè)控制[4]。</p><p> C shell 是在加州大學柏克來分校于70年代末期發(fā)展而成,而以2BSD UNIX的部分發(fā)行。這個 shell 主要是由 Bill Joy 寫成,提供了一些在標準 Bourne shell 所看不到的額外特色。C shell 是以C 程序語言作為基礎,且它被用來當程序語言時,能共享類似的語法
20、。它也提供在交談式運用上的改進,例如命令列歷程、別名和作業(yè)控制。因為 C shell 是在大型機器上設計出來,且增加了一些額外功能,所以 C shell 有在小型機器上跑得較慢,即使在大型機器上跟 Bourne shell 比起來也顯得緩慢。</p><p> 有了 Bourne shell 和 C shell 之后,UNIX 使用者就有了選擇,且爭論那一個 shell 較好。AT&T 的David K
21、orn 在 80 年代中期發(fā)明了 Korn shell,在 1986 年發(fā)行且在 1988 年成為正式的部分 SVR4 UNIX。Korn shell 實際上是 Bourne shell 的超集,且不只可在 UNIX 系統(tǒng)上執(zhí)行,同時也可在 OS/2、VMS、和 DOS上執(zhí)行。它提供了和 Bourne shell 向上兼容的能力,且增加了許多在 C shell 上受歡迎的特色,更增加了速度和效率。 Korn shell 已歷經許多修正版
22、,要找尋用戶使用的是那一個版本可在 ksh 提示符號下按 Ctrl-v 鍵。</p><p> 在大部份的UNIX系統(tǒng),三種著名且廣被支持的shell 是Bourne shell(AT&T shell,在 Linux 下是BASH)、C shell(Berkeley shell,在 Linux 下是TCSH)和 Korn shell(Bourne shell的超集)。這三種 shell 在交互(inte
23、ractive)模式下的表現相當類似,但作為命令文件語言時,在語法和執(zhí)行效率上就有些不同了。</p><p> Bourne shell 是標準的 UNIX shell,以前常被用來做為管理系統(tǒng)之用。大部份的系統(tǒng)管理命令文件,例如 rc start、stop 與shutdown 都是Bourne shell 的命令,且在單用戶模式(single user mode)下以 root 登錄時它常被系統(tǒng)管理員使用。B
24、ourne shell 是由 AT&T 發(fā)展的,以簡潔、快速著名。 Bourne shell 提示符號的默認值是’$‘。</p><p> C shell 是柏克萊大學(Berkeley)所開發(fā)的,且加入了一些新特性,如命令列歷程(history)、別名(alias)、內建算術、文件名完成(filename completion)、和作業(yè)控制(job control)。對于常在交互模式下執(zhí)行 shell
25、 的使用者而言,他們較喜愛使用 C shell;但對于系統(tǒng)管理者而言,則較偏好以 Bourne shell 來做命令,因為 Bourne shell 命令比 C shell 命令來的簡單及快速。C shell 提示符號的默認值是’% ‘。</p><p> 1.2 課題研究的目的與意義</p><p> 編寫簡單的shell命令例如ls,cp,cat和rm命令等并且介紹了Shell相
26、關的外部程序命令及管道和輸入輸出重定向功能,以加深對Shell這方面知識的理解,為此類程序的開發(fā)提供一定的啟示性和指導性。</p><p> 本課題的目的是linux下的shell實現和開發(fā),通過c語言寫出shell下的命令,通過c的實現,更加了解管道和輸入輸出重定向,進一步加深對linux系統(tǒng)的了解。</p><p> 1.3 課題的研究內容</p><p>
27、;<b> 研究的基本內容:</b></p><p> 在Linux環(huán)境下編寫一個簡單的shell程序,達到以下要求:</p><p> ?。?)能夠執(zhí)行外部程序命令,命令可以帶參數;</p><p> (2)能夠實現管道和輸入輸出重定向功能。</p><p> 實現的shell能夠解釋并執(zhí)行下列命令:</
28、p><p> ?。?)ls 列目錄</p><p> 功能:顯示文件和目錄的信息</p><p> ls 以默認方式顯示當前目錄文件列表</p><p> ls -a 顯示所有文件包括隱藏文件</p><p> ls -l 顯示文件屬性,包括大小,日期,符號連接,是否可讀寫及是否可執(zhí)行</p>
29、<p> ls -lh 顯示文件的大小,以容易理解的格式印出文件大小 (例如 1K 234M 2G)</p><p> ls -lt 顯示文件,按照修改時間排序</p><p> ?。?)cp 文件拷貝</p><p><b> 功能:copy文件</b></p><p> cp source t
30、arget 將文件source復制為target</p><p> cp /root /source. 將/root下的文件source復制到當前目錄</p><p> cp ? av soure_dir target_dir 將整個目錄復制,兩目錄完全一樣</p><p> ?。?)rm 刪除文件</p><p> 功能:
31、 刪除文件`或目錄</p><p> rm file 刪除某一個文件</p><p> rm -f file 刪除時候不進行提示??梢杂趓參數配合使用</p><p> rm -rf dir 刪除當前目錄下叫dir的整個目錄</p><p> (4)who 顯示當前登錄的用戶信息</p><p&
32、gt;<b> 功能:顯示登錄用戶</b></p><p> (5)cat 顯示文件內容</p><p> 顯示文件的內容,和DOS的type相同</p><p> 2 Linux下shell的開發(fā)方法</p><p> 2.1 c語言簡介</p><p> C語言是一種計算機
33、程序設計語言。它既有高級語言的特點,又具有匯編語言的特點。它可以作為系統(tǒng)設計語言,編寫工作系統(tǒng)應用程序,也可以作為應用程序設計語言,編寫不依賴計算機硬件的應用程序。因此,它的應用范圍廣泛。 C語言對操作系統(tǒng)和系統(tǒng)使用程序以及需要對硬件進行操作的場合,用C語言明顯優(yōu)于其它解釋型高級語言,有一些大型應用軟件也是用C語言編寫的。 C語言具有繪圖能力強,可移植性,并具備很強的數據處理能力,因此適于編寫系統(tǒng)軟件,三維,二維圖形
34、和動畫。它是數值計算的高級語言。 常用的C語言IDE(集成開發(fā)環(huán)境)有Microsoft Visual C++,Borland C++,Watcom C++ ,Borland C++ Borland C++ Builder,Borland C++ 3.1 for DOS,Watcom C+
35、+ 11.0 for DOS,GNU DJGPP C++ Lccwin32 C Compiler 3.1,Microsoft C,High C,TurboC等等...... </p><p> 2..2 c 語言的結構特點:</p><p> 1.一個C語言源程序可
36、以由一個或多個源文件組成。 </p><p> 2.每個源文件可由一個或多個函數組成。 </p><p> 3.一個源程序不論由多少個文件組成,都有一個且只能有一個main函數,即主函數。 </p><p> 4.源程序中可以有預處理命令(include 命令僅為其中的一種),預處理命令通常應放在源文件或源程序的最前面。
37、 </p><p> 5.每一個說明,每一個語句都必須以分號結尾。但預處理命令,函數頭和花括號“}”之后不能加分號。 </p><p> 6.標識符,關鍵字之間必須至少加一個空格以示間隔。若已有明顯的間隔符,也可不再加空格來間隔。</p><p> 2.3 c 語言的優(yōu)點</p><p> 1. 簡潔緊
38、湊、靈活方便 </p><p> C語言一共只有32個關鍵字,9種控制語句,程序書寫自由,主要用小寫字母表示。它把高級語言的基本結構和語句與低級語言的實用性結合起來。 C 語言可以象匯編語言一樣對位、字節(jié)和地址進行操作, 而這三者是計算機最基本的工作單元。 </p><p><b> 2. 運算符豐富 &l
39、t;/b></p><p> C的運算符包含的范圍很廣泛,共有種34個運算符。C語言把括號、賦值、強制類型轉換等都作為運算符處理。從而使C的運算類型極其豐富表達式類型多樣化,靈活使用各種運算符可以實現在其它高級語言中難以實現的運算。 </p><p> 3. 數據結構豐富 </p><p> C的數據類型有:整型、實型、字符
40、型、數組類型、指針類型、結構體類型、共用體類型等。能用來實現各種復雜的數據類型的運算。并引入了指針概念,使程序效率更高。另外C語言具有強大的圖形功能, 支持多種顯示器和驅動器。且計算功能、邏輯判斷功能強大。 </p><p> 4. C是結構式語言 </p><p> 結構式語言的顯著特點是代碼及數據的分隔化,即程序的各個部分除了必要的信息交流外
41、彼此獨立。這種結構化方式可使程序層次清晰, 便于使用、維護以及調試。C語言是以函數形式提供給用戶的,這些函數可方便的調用,并具有多種循環(huán)、條件語句控制程序流向,從而使程序完全結構化。 </p><p> 5. C語法限制不太嚴格,程序設計自由度大 </p><p> 雖然C語言也是強類型語言,但它的語法比較靈活,允許程序編寫者有較大的自由度。
42、160;</p><p> 6. C語言允許直接訪問物理地址,可以直接對硬件進行操作 因此既具有高級語言的功能,又具有低級語言的許多功能,能夠象匯編語言一樣對位、字節(jié)和地址進行操作,而這三者是計算機最基本的工作單元,可以用來寫系統(tǒng)軟件。 </p><p> 7. C語言程序生成代碼質量高,程序執(zhí)行效率高 一般只比匯編程序生成的目標代碼效
43、率低10へ20%。 </p><p> 8. C語言適用范圍大,可移植性好 </p><p> C語言有一個突出的優(yōu)點就是適合于多種操作系統(tǒng), 如DOS、UNIX,也適用于多種機型。</p><p><b> 2.4 c語言缺點</b></p><p> 1. C
44、語言的缺點主要是表現在數據的封裝性上,這一點使得C在數據的安全性上做的有很大缺陷,這也是C和C++的一大區(qū)別。 </p><p> 2. C語言的語法限制不太嚴格,對變量的類型約束不嚴格,影響程序的安全性,對數組下標越界不作檢查等。從應用的角度,C語言比其他高級語言較難掌握。 [C語言指針] 指針就是C語言的一大特色,可以說C語言優(yōu)于其它高級語言的一個重要原因就是因為它有
45、指針操作可以直接進行靠近硬件的操作,但是C的指針操作也給它帶來了很多不安全的因素。C++在這方面做了很好的改進,在保留了指針操作的同時又增強了安全性。Java取消了指針操作,提高了安全性。</p><p> 2.5 shell概念</p><p> Shell是一種具備特殊功能的程序,它是介于使用者和 UNIX/Linux 操作系統(tǒng)之核心程序(kernel)間的一個接口。為什么我們說
46、 shell 是一種介于系統(tǒng)核心程序與使用者間的中介者呢?讀過操作系統(tǒng)概論的讀者們都知道操作系統(tǒng)是一個系統(tǒng)資源的管理者與分配者,當您有需求時,您得向系統(tǒng)提出;從操作系統(tǒng)的角度來看,它也必須防止使用者因為錯誤的操作而造成系統(tǒng)的傷害?眾所周知,對計算機下命令得透過命令(command)或是程序(program);程序有編譯器(compiler)將程序轉為二進制代碼,可是命令呢?其實shell 也是一支程序,它由輸入設備讀取命令,再將其轉為計
47、算機可以了解的機械碼,然后執(zhí)行它。 </p><p> 各種操作系統(tǒng)都有它自己的 shell,以 DOS 為例,它的 shell 就是 command.com 檔。如同 DOS 下有 NDOS,4DOS,DRDOS 等不同的命令解譯程序可以取代標準的 command.com ,UNIX 下除了 Bourne shell(/bin/sh) 外還有 C shell(/bin/csh)、Korn shell
48、(/bin/ksh)、Bourne again shell(/bin/bash)、Tenex C shell(tcsh) … 等其它的 shell。UNIX/Linux 將 shell 獨立于核心程序之外,使得它就如同一般的應用程序,可以在不影響操作系統(tǒng)本身的情況下進行修改、更新版本或是添加新的功能。 </p><p> 在系統(tǒng)起動的時候,核心程序會被加載內存,負責管理系統(tǒng)的工作,直到系統(tǒng)關閉為止。它
49、建立并控制著處理程序,管理內存、檔案系統(tǒng)、通訊等等。而其它的程序,包括 shell 程序,都存放在磁盤中。核心程序將它們加載內存,執(zhí)行它們,并且在它們中止后清理系統(tǒng)。Shell 是一個公用程序,它在您簽入時起動。藉由解譯使用者輸入的命令(由命令列或命令檔),Shell 提供使用者和核心程序產生交談的功能。 </p><p> 不論是哪一種Shell,它最主要的功用都是解譯使用者在命令列提示符號下輸入的
50、指令。Shell 語法分析命令列,把它分解成以空白區(qū)分開的符號(token),在此空白包括了跳位鍵(tab)、空白和換行(New Line)。如果這些字包含了metacharacter,shell 將會評估(evaluate)它們的正確用法。另外,shell 還管理檔案輸入輸出及幕后處理(background processing)。在處理命令列之后,shell 會尋找命令并開始執(zhí)行它們。 </p><p&
51、gt; Shell 的另一個重要功用是提供個人化的使用者環(huán)境,這通常在 shell 的初始化檔案中完成(.profile、.login、.cshrc、.tcshrc 等等)。這些檔案包括了設定終端機鍵盤和定義窗口的特征;設定變量,定義搜尋路徑、權限限、提示符號和終端機類形;以及設定特殊應用程序所需要的變量,例如窗口、文字處理程序、及程序語言的鏈接庫。Korn shell 和 C shell 加強了個別化的能力:增加歷程、別名、和內建變
52、量集以避免使用者誤殺檔案、不慎簽出、并在當工作完成時通知使用者。</p><p> Shell 也能當解譯性的程序語言(interpreted programing language)。Shell 程序,通常叫做命令文件,它由列在檔案內的命令所構成。此程序在編輯器中編輯(雖然也可以直接在命令列下寫作程序, online scripting),由 UNIX 命令和基本的程序結構,例如變量的指定、測試條件、和循環(huán)所
53、構成。您不需要編譯 shell 命令檔。Shell 本身會解譯命令檔中的每一行,就如同由鍵盤輸入一樣。shell 負責解譯命令,而使用者則必須了解這些命令能做什么。這本書的索引列出了一些有用的命令和它們的使用方法。 </p><p> 2.6 shell語言</p><p> 從程序員的角度來看, Shell本身是一種用C語言編寫的程序,從用戶的角度來看,Shell是用戶與
54、Linux操作系統(tǒng)溝通的橋梁。用戶既可以輸入命令執(zhí)行,又可以利用 Shell腳本編程,完成更加復雜的操作。在Linux GUI日益完善的今天,在系統(tǒng)管理等領域,Shell編程仍然起著不可忽視的作用。深入地了解和熟練地掌握Shell編程,是每一個Linux用戶的必修 功課之一。</p><p> Linux的Shell種類眾多,常見的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bour
55、ne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等等。不同的Shell語言的語法有所不同,所以不能交換使用。每種Shell都有其特色之處,基本上,掌握其中任何一種 就足夠了。在本文中,我們關注的重點是Bash,也就是Bourne Again Shell,由于易用和免費,Bash在日常工作中被廣泛使
56、用;同時,Bash也是大多數Linux系統(tǒng)默認的Shell。在一般情況下,人們并不區(qū)分 Bourne Shell和Bourne Again Shell,所以,在下面的文字中,我們可以看到#!/bin/sh,它同樣也可以改為#!/bin/bash。</p><p> 利用vi等文本編輯器編寫Shell腳本的格式是固定的,如下:</p><p><b> #!/bin/sh<
57、;/b></p><p><b> #comments</b></p><p> Your commands go here</p><p> 首行中的符號#!告訴系統(tǒng)其后路徑所指定的程序即是解釋此腳本文件的Shell程 序。如果首行沒有這句話,在執(zhí)行腳本文件的時候,將會出現錯誤。后續(xù)的部分就是主程序,Shell腳本像高級語言一樣,
58、也有變量賦值,也有控制語句。除第 一行外,以#開頭的行就是注釋行,直到此行的結束。如果一行未完成,可以在行尾加上",這個符號表明下一行與此行會合并為同一行。</p><p> 編輯完畢,將腳本存盤為filename.sh,文件名后綴sh表明這是一個Bash腳本文件。執(zhí)行腳本的時候,要先將腳本文件的屬性改為可執(zhí)行的:</p><p> chmod +x filename.sh&
59、lt;/p><p><b> 執(zhí)行腳本的方法是:</b></p><p> ./filename.sh</p><p> 下面我們從經典的“hello world”入手,看一看最簡單的Shell腳本的模樣。</p><p><b> #!/bin/sh</b></p><p&
60、gt; #print hello world in the console window</p><p> a = "hello world"</p><p><b> echo $a</b></p><p> Shell Script是一種弱類型語言,使用變量的時候無需首先聲明其類型。新的變量會在本地數據區(qū)分配內存
61、進行存儲,這個變量歸當前的Shell所有,任何子進 程都不能訪問本地變量。這些變量與環(huán)境變量不同,環(huán)境變量被存儲在另一內存區(qū),叫做用戶環(huán)境區(qū),這塊內存中的變量可以被子進程訪問。變量賦值的方式是:</p><p> variable_name = variable_value</p><p> 如果對一個已經有值的變量賦值,新值將取代舊值。取值的時候要在變量名前加$,$variable_
62、name可以在引號中使用,這一點和其他高級語言是明顯不同的。如果出現混淆的情況,可以使用花括號來區(qū)分,例如:</p><p> echo "Hi, $as"</p><p> 就不會輸出“Hi, hello worlds”,而是輸出“Hi,”。這是因為Shell把$as當成一個變量,而$as未被賦值,其值為空。正確的方法是:</p><p>
63、 echo "Hi, ${a}s"</p><p> 單引號中的變量不會進行變量替換操作。 </p><p> 關于變量,還需要知道幾個與其相關的Linux命令。</p><p> env用于顯示用戶環(huán)境區(qū)中的變量及其取值;set用于顯示本地數據區(qū)和用戶環(huán)境區(qū)中的變量及其取值;unset用于刪除指定變量當前的取值,該值將被指定為
64、NULL;export命令用于將本地數據區(qū)中的變量轉移到用戶環(huán)境區(qū)。</p><p> 3 開發(fā)工具和開發(fā)環(huán)境介紹</p><p> 3.1 gcc 簡介</p><p> Linux系統(tǒng)下的Gcc(GNU C Compiler)是GNU推出的功能強大、性能優(yōu)越的多</p><p> 臺編譯器,是GNU的代表作品之一。gcc是可以
65、在多種硬體平臺上編譯出可執(zhí)行程序的超級編譯器,其執(zhí)行效率與一般的編譯器相比平均效率要高20%~30%。 Gcc編譯器能將C、C++語言源程序、匯程式化序和目標程序編譯、連接成可執(zhí)行文件,如果沒有給出可執(zhí)行文件的名字,gcc將生成一個名為a.out的文件。在Linux系統(tǒng)中,可執(zhí)行文件沒有統(tǒng)一的后綴,系統(tǒng)從文件的屬性來區(qū)分可執(zhí)行文件和不可執(zhí)行文件。而gcc則通過后綴來區(qū)別輸入文件的類別,下面我們來介紹gcc所遵循的部分約定規(guī)則。 <
66、/p><p> .c為后綴的文件,C語言源代碼文件; </p><p> .a為后綴的文件,是由目標文件構成的檔案庫文件; </p><p> .C,.cc或.cxx 為后綴的文件,是C++源代碼文件; </p><p> .h為后綴的文件,是程序所包含的頭文件; </p><p> .i 為后綴的文件,是已經預
67、處理過的C源代碼文件; </p><p> .ii為后綴的文件,是已經預處理過的C++源代碼文件; </p><p> .m為后綴的文件,是Objective-C源代碼文件; </p><p> .o為后綴的文件,是編譯后的目標文件; </p><p> .s為后綴的文件,是匯編語言源代碼文件; </p><p&g
68、t; .S為后綴的文件,是經過預編譯的匯編語言源代碼文件。 </p><p> Gcc的執(zhí)行過程: </p><p> 雖然我們稱Gcc是C語言的編譯器,但使用gcc由C語言源代碼文件生成可執(zhí)行文</p><p> 過程不僅僅是編譯的過程,而是要經歷四個相互關聯的步驟∶預處理(也稱預編譯,Preprocessing)、編譯(Compilation)、匯編(A
69、ssembly)和連接(Linking)。 </p><p> 命令gcc首先調用cpp進行預處理,在預處理過程中,對源代碼文件中的文件包含(include)、預編譯語句(如宏定義define等)進行分析。接著調用cc1進行編譯,這個階段根據輸入文件生成以.o為后綴的目標文件。匯編過程是針對匯編語言的步驟,調用as進行工作,一般來講,.S為后綴的匯編語言源代碼文件和匯編、.s為后綴的匯編語言文件經過預編譯和匯編
70、之后都生成以.o為后綴的目標文件。當所有的目標文件都生成之后,gcc就調用ld來完成最后的關鍵性工作,這個階段就是連接。在連接階段,所有的目標文件被安排在可執(zhí)行程序中的恰當的位置,同時,該程序所調用到的庫函數也從各自所在的檔案庫中連到合適的地方。</p><p> 3.2 Gcc的基本用法和選項 </p><p> 在使用Gcc編譯器的時候,我們必須給出一系列必要的調用參數和文件名稱。
71、Gcc編譯器的調用參數大約有100多個,其中多數參數我們可能根本就用不到,這里只介紹其中最基本、最常用的參數。 </p><p> Gcc最基本的用法是∶gcc [options] [filenames] </p><p> 其中options就是編譯器所需要的參數,filenames給出相關的文件名稱。 </p><p> -c,只編譯,不連接成為可執(zhí)行文件
72、,編譯器只是由輸入的.c等源代碼文件生成.o為后綴的目標文件,通常用于編譯不包含主程序的子程序文件。 </p><p> -o output_filename,確定輸出文件的名稱為output_filename,同時這個名稱不能和源文件同名。如果不給出這個選項,gcc就給出預設的可執(zhí)行文件a.out。 </p><p> -g,產生符號調試工具(GNU的gdb)所必要的符號資訊,要想對
73、源代碼進行調試,我們就必須加入這個選項。 </p><p> -O,對程序進行優(yōu)化編譯、連接,采用這個選項,整個源代碼會在編譯、連接過程中進行優(yōu)化處理,這樣產生的可執(zhí)行文件的執(zhí)行效率可以提高,但是,編譯、連接的速度就相應地要慢一些。 </p><p> -O2,比-O更好的優(yōu)化編譯、連接,當然整個編譯、連接過程會更慢。 </p><p> -Idirname,
74、將dirname所指出的目錄加入到程序頭文件目錄列表中,是在預編譯過程中使用的參數。C程序中的頭文件包含兩種情況∶ </p><p> A)#include </p><p> B)#include “myinc.h” </p><p> 其中,A類使用尖括號(< >),B類使用雙引號(“ ”)。對于A類,預處理程序cpp在系統(tǒng)預設包含文件目錄(如
75、/usr/include)中搜尋相應的文件,而對于B類,cpp在當前目錄中搜尋頭文件,這個選項的作用是告訴cpp,如果在當前目錄中沒有找到需要的文件,就到指定的dirname目錄中去尋找。在程序設計中,如果我們需要的這種包含文件分別分布在不同的目錄中,就需要逐個使用-I選項給出搜索路徑。 </p><p> -Ldirname,將dirname所指出的目錄加入到程序函數檔案庫文件的目錄列表中,是在連接過程中使用
76、的參數。在預設狀態(tài)下,連接程序ld在系統(tǒng)的預設路徑中(如/usr/lib)尋找所需要的檔案庫文件,這個選項告訴連接程序,首先到-L指定的目錄中去尋找,然后到系統(tǒng)預設路徑中尋找,如果函數庫存放在多個目錄下,就需要依次使用這個選項,給出相應的存放目錄。 </p><p> -lname,在連接時,裝載名字為“l(fā)ibname.a”的函數庫,該函數庫位于系統(tǒng)預設的目錄或者由-L選項確定的目錄下。例如,-lm表示連接名為
77、“l(fā)ibm.a”的數學函數庫。 </p><p> 上面我們簡要介紹了gcc編譯器最常用的功能和主要參數選項,更為詳盡的資料可以參看Linux系統(tǒng)的聯機幫助。 </p><p> 假定我們有一個程序名為test.c的C語言源代碼文件,要生成一個可執(zhí)行文件,最簡單的辦法就是∶ </p><p> gcc test.c </p><p>
78、 這時,預編譯、編譯連接一次完成,生成一個系統(tǒng)預設的名為a.out的可執(zhí)行文件,對于稍為復雜的情況,比如有多個源代碼文件、需要連接檔案庫或者有其他比較特別的要求,就要給定適當的調用選項參數。再看一個簡單的例子。 </p><p> 整個源代碼程序由兩個文件testmain.c 和testsub.c組成,程序中使用了系統(tǒng)提供的數學庫,同時希望給出的可執(zhí)行文件為test,這時的編譯命令可以是∶ </p>
79、<p> gcc testmain.c testsub.c □lm □o test </p><p> 其中,-lm表示連接系統(tǒng)的數學庫libm.a。 </p><p> Gcc的錯誤類型及對策 </p><p> Gcc編譯器如果發(fā)現源程序中有錯誤,就無法繼續(xù)進行,也無法生成最終的可執(zhí)行文件。為了便于修改,gcc給出錯誤資訊,我們必須對這些錯
80、誤資訊逐個進行分析、處理,并修改相應的語言,才能保證源代碼的正確編譯連接。gcc給出的錯誤資訊一般可以分為四大類,下面我們分別討論其產生的原因和對策。 </p><p> 第一類∶C語法錯誤 </p><p> 錯誤資訊∶文件source.c中第n行有語法錯誤(syntex errror)。這種類型的錯誤,一般都是C語言的語法錯誤,應該仔細檢查源代碼文件中第n行及該行之前的程序,有時也
81、需要對該文件所包含的頭文件進行檢查。有些情況下,一個很簡單的語法錯誤,gcc會給出一大堆錯誤,我們最主要的是要保持清醒的頭腦,不要被其嚇倒,必要的時候再參考一下C語言的基本教材。 </p><p> 第二類∶頭文件錯誤 </p><p> 錯誤資訊∶找不到頭文件head.h(Can not find include file head.h)。這類錯誤是源代碼文件中的包含頭文件有問題,可
82、能的原因有頭文件名錯誤、指定的頭文件所在目錄名錯誤等,也可能是錯誤地使用了雙引號和尖括號。 </p><p> 第三類∶檔案庫錯誤 </p><p> 錯誤資訊∶連接程序找不到所需的函數庫,例如∶ </p><p> ld: -lm: No such file or directory </p><p> 這類錯誤是與目標文件相連接的
83、函數庫有錯誤,可能的原因是函數庫名錯誤、指定的函數庫所在目錄名稱錯誤等,檢查的方法是使用find命令在可能的目錄中尋找相應的函數庫名,確定檔案庫及目錄的名稱并修改程序中及編譯選項中的名稱。 </p><p> 第四類∶未定義符號 </p><p> 錯誤資訊∶有未定義的符號(Undefined symbol)。這類錯誤是在連接過程中出現的,可能有兩種原因∶一是使用者自己定義的函數或者全
84、局變量所在源代碼文件,沒有被編譯、連接,或者干脆還沒有定義,這需要使用者根據實際情況修改源程序,給出全局變量或者函數的定義體;二是未定義的符號是一個標準的庫函數,在源程序中使用了該庫函數,而連接過程中還沒有給定相應的函數庫的名稱,或者是該檔案庫的目錄名稱有問題,這時需要使用檔案庫維護命令ar檢查我們需要的庫函數到底位于哪一個函數庫中,確定之后,修改gcc連接選項中的-l和-L項。 </p><p> 排除編譯、
85、連接過程中的錯誤,應該說這只是程序設計中最簡單、最基本的一個步驟,可以說只是開了個頭。這個過程中的錯誤,只是我們在使用C語言描述一個算法中所產生的錯誤,是比較容易排除的。我們寫一個程序,到編譯、連接通過為止,應該說剛剛開始,程序在運行過程中所出現的問題,是算法設計有問題,說得更玄點是對問題的認識和理解不夠,還需要更加深入地測試、調試和修改。一個程序,稍為復雜的程序,往往要經過多次的編譯、連接和測試、修改。</p><
86、p> 4 基本功能和實現方法</p><p> 在Linux環(huán)境下編寫一個簡單的shell程序,達到以下要求:</p><p> (1)能夠執(zhí)行外部程序命令,命令可以帶參數;</p><p> (2)能夠實現管道和輸入輸出重定向功能。</p><p><b> 擬解決的主要問題:</b></p&g
87、t;<p> 實現的shell能夠解釋并執(zhí)行下列命令:</p><p> (1)ls 列目錄</p><p> 功能:顯示文件和目錄的信息</p><p> ls 以默認方式顯示當前目錄文件列表</p><p> ls -a 顯示所有文件包括隱藏文件</p><p> ls -l 顯示文
88、件屬性,包括大小,日期,符號連接,是否可讀寫及是否可執(zhí)行</p><p> ls -lh 顯示文件的大小,以容易理解的格式印出文件大小 (例如 1K 234M 2G)</p><p> ls -lt 顯示文件,按照修改時間排序</p><p> (2)cp 文件拷貝</p><p><b> 功能:copy文件<
89、/b></p><p> cp source target 將文件source復制為target</p><p> cp /root /source. 將/root下的文件source復制到當前目錄</p><p> cp ? av soure_dir target_dir 將整個目錄復制,兩目錄完全一樣</p><p> ?。?
90、)rm 刪除文件</p><p> 功能: 刪除文件`或目錄</p><p> rm file 刪除某一個文件</p><p> rm -f file 刪除時候不進行提示。可以于r參數配合使用</p><p> rm -rf dir 刪除當前目錄下叫dir的整個目錄</p><p>
91、 ?。?)who 顯示當前登錄的用戶信息</p><p><b> 功能:顯示登錄用戶</b></p><p><b> 例如:</b></p><p><b> # who</b></p><p> zhoulj pts/0 Mar 13 21:
92、24 (10.140.0.109)</p><p> ?。?)cat 顯示文件內容</p><p> 顯示文件的內容,和DOS的type相同</p><p><b> cat file</b></p><p> 5 主要源代碼介紹</p><p><b> 5.1 ls功能
93、</b></p><p> #include <stdio.h></p><p> #include <sys/types.h></p><p> #include <dirent.h></p><p> #include <sys/stat.h></p>&l
94、t;p> #include<stdlib.h></p><p> #include<string.h></p><p> void do_ls(char[]);</p><p> void dostat(char *);</p><p> void show_file_info(char *,struc
95、t stat *);</p><p> void mode_to_letters(int,char[]);</p><p> char * uid_to_name(uid_t);</p><p> char *gid_to_name(gid_t);</p><p> main(int ac, char *av[])</p>
96、<p><b> {</b></p><p><b> if(ac==1)</b></p><p> do_ls(".");</p><p><b> else</b></p><p> while(--ac)</p>
97、<p><b> {</b></p><p> printf("%s:\n",*++av);</p><p> do_ls(*av);</p><p><b> }</b></p><p><b> }</b></p>&l
98、t;p> void do_ls(char dirname[])</p><p><b> {</b></p><p> DIR *dir_ptr;</p><p> struct dirent *direntp;</p><p> if((dir_ptr=opendir(dirname))== NULL)
99、</p><p> fprintf(stderr,"ls1:cannot open %s\n",dirname);</p><p><b> else</b></p><p><b> {</b></p><p> while ((direntp=readdir(dir_
100、ptr))!=NULL)</p><p> dostat(direntp->d_name);</p><p> closedir(dir_ptr);</p><p><b> }</b></p><p><b> }</b></p><p> void dos
101、tat(char *filename)</p><p><b> {</b></p><p> struct stat info;</p><p> if(stat(filename,&info)== -1)</p><p> perror(filename);</p><p>&
102、lt;b> else</b></p><p> show_file_info(filename,&info);</p><p><b> }</b></p><p> void show_file_info(char *filename,struct stat *info_p)</p><p
103、><b> {</b></p><p> char *uid_to_name(),*ctime(),*gid_to_name(),*filemode();</p><p> void mode_to_letters();</p><p> char modestr[11];</p><p> mode_t
104、o_letters(info_p->st_mode,modestr);</p><p> printf("%s",modestr);</p><p> printf("%4d",(int)info_p->st_nlink);</p><p> printf("%-8s",uid_to_na
105、me(info_p->st_uid));</p><p> printf("%-8s",gid_to_name(info_p->st_gid));</p><p> printf("%-8ld",(long)info_p->st_size);</p><p> printf("%-12.12s
106、",ctime(&info_p->st_mtime)+4);</p><p> printf(" %s\n",filename);</p><p><b> }</b></p><p> void mode_to_letters(int mode,char str[])</p>
107、<p><b> {</b></p><p> strcpy(str,"----------");</p><p> if(S_ISDIR(mode)) str[0]='d';</p><p> if(S_ISCHR(mode)) str[0]='c';</p>
108、<p> if(S_ISBLK(mode)) str[0]='b';</p><p> if(mode&S_IRUSR) str[1]='r';</p><p> if(mode&S_IWUSR) str[2]='w';</p><p> if(mode&S_IXUSR)
109、 str[3]='x';</p><p> if(mode&S_IRGRP) str[4]='r';</p><p> if(mode&S_IWGRP) str[5]='w';</p><p> if(mode&S_IXGRP) str[6]='x';</p&
110、gt;<p> if(mode&S_IROTH) str[7]='r';</p><p> if(mode&S_IWOTH) str[8]='w';</p><p> if(mode&S_IXOTH) str[9]='x';</p><p><b> }&l
111、t;/b></p><p> #include <pwd.h></p><p> char * uid_to_name( uid_t uid)</p><p><b> {</b></p><p> struct passwd *getpwuid(),*pw_ptr;</p>&l
112、t;p> static char numstr[10];</p><p> if((pw_ptr=getpwuid(uid))==NULL)</p><p><b> {</b></p><p> struct passwd * getpwuid(),* pw_ptr;</p><p> static
113、char numstr[10];</p><p> sprintf(numstr,"%d",uid);</p><p> return numstr;</p><p><b> }</b></p><p><b> else </b></p><p&g
114、t; return pw_ptr->pw_name;</p><p><b> }</b></p><p> #include <grp.h></p><p> char *gid_to_name(gid_t gid)</p><p><b> {</b></p&g
115、t;<p> struct group *getgrgid(),*grp_ptr;</p><p> static char numstr[10];</p><p> if((grp_ptr=getgrgid(gid))==NULL)</p><p><b> {</b></p><p> spr
116、intf(numstr,"%d",gid);</p><p> return numstr;</p><p><b> }</b></p><p><b> else</b></p><p> return grp_ptr->gr_name; </p>
117、<p><b> ls 功能界面</b></p><p> 圖1-1 顯示ls功能</p><p><b> 5.2 cp功能</b></p><p> #include <stdio.h></p><p> #include <unistd.h><
118、;/p><p> #include <fcntl.h></p><p> #include<stdlib.h></p><p> #define BUFFERSIZE 4096</p><p> #define COPYMODE 0644</p><p> void oops(
119、char*,char*);</p><p> main(int ac,char *av[])</p><p><b> {</b></p><p> int in_fd,out_fd,n_chars;</p><p> char buf[BUFFERSIZE];</p><p> if(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- linux shell的 研 究 與 開 發(fā)【畢業(yè)設計+開題報告+文獻綜述】
- linux shell的設計與實現【畢業(yè)設計】
- linux shell的設計與實現【畢業(yè)設計+開題報告+文獻綜述】
- linux shell的設計與實現【文獻綜述】
- linux shell的設計與實現【開題報告】
- linux shell的設計與實現開題報告
- linux shell大作業(yè)
- linux shell的研究與開發(fā)【文獻綜述】
- linux shell的研究與開發(fā)【開題報告】
- linux的應用及shell編程
- linux下shell的工作原理
- linux主要shell命令詳解
- 雨 衣 的 研 究
- linux下的shell項目知識累積
- linux網絡聊天畢業(yè)設計
- Unix-Linux服務器Shell審計平臺的設計與實現.pdf
- linux平臺下的聊天軟件的設計與開發(fā)畢業(yè)設計
- 畢業(yè)設計-linux網絡入侵檢測系統(tǒng)設計與實現
- linux大作業(yè)課程設計說明書-linux unix shell腳本編程
- 開合螺母夾具設計畢業(yè)設計
評論
0/150
提交評論