嵌入式系統(tǒng)原理與應(yīng)用 課件 第8、9章 Linux下的Shell命令與編程、Linux下程序設(shè)計工具_第1頁
嵌入式系統(tǒng)原理與應(yīng)用 課件 第8、9章 Linux下的Shell命令與編程、Linux下程序設(shè)計工具_第2頁
嵌入式系統(tǒng)原理與應(yīng)用 課件 第8、9章 Linux下的Shell命令與編程、Linux下程序設(shè)計工具_第3頁
嵌入式系統(tǒng)原理與應(yīng)用 課件 第8、9章 Linux下的Shell命令與編程、Linux下程序設(shè)計工具_第4頁
嵌入式系統(tǒng)原理與應(yīng)用 課件 第8、9章 Linux下的Shell命令與編程、Linux下程序設(shè)計工具_第5頁
已閱讀5頁,還剩151頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

嵌入式系統(tǒng)原理與設(shè)計第8章Linux下的Shell命令與編程第八章01020304基本概念常用Shell命令Shell編程基礎(chǔ)Shell編程的控制語句/01基本概念Shell簡介1.什么是ShellLinux系統(tǒng)中,Shell就是套在操作系統(tǒng)內(nèi)核外面的一層殼。正因為Shell的存在,才向普通用戶隱藏了許多關(guān)于操作系統(tǒng)內(nèi)核的細節(jié),方便了用戶使用計算機。2.Shell的功能Shell的基本功能是進行命令解釋和執(zhí)行,用來接收用戶輸入的命令,并傳遞給操作系統(tǒng)。Shell的擴展功能是一種程序設(shè)計語言,利用Shell規(guī)定的語法,可以設(shè)計出各種功能的程序來更方便的管理或使用計算機。Shell簡介Shell的版本BourneShell:簡稱sh,該Shell由SteveBourne在貝爾實驗室時編寫。Bourne-AgainShell:簡稱bash,該Shell由BrianFox編寫,是絕大多數(shù)GNULinux發(fā)行版的默認Shell。CShell:簡稱csh,該Shell由Billjoy在BSD系統(tǒng)上開發(fā),由于其語法類似于C語言,因此稱為CShell。ZShell:Thelastshellyou’lleverneed!Z是最后一個字母,也就是終極Shell。它集成bash、csh的重要特性,同時又增加了獨有的特性。Shell簡介Shell編程的應(yīng)用場景在嵌入式系統(tǒng)開發(fā)過程中,以下場景都可以通過Shell編程簡化工作:將一些復雜的命令簡單化。例如:在GitHub上提交一次代碼需要很多步驟,但是用Shell之后就可以簡化成一步。在項目開發(fā)中,通過腳本自動實現(xiàn)更新最新的軟件開發(fā)工具包(SDK)。能夠批量處理,大部分操作過程位于后臺,不需要用戶進行干預。自動打包、編譯、發(fā)布等功能。Linux下目錄與路徑Linux系統(tǒng)中,目錄就是描述所有文件信息的樹型結(jié)構(gòu),如圖所示。Work目錄(工作目錄)Home目錄(家目錄)Linux下目錄與路徑

路徑指從樹型目錄中的某個節(jié)點(起點)到另一個節(jié)點(終點)經(jīng)過的節(jié)點次序,起點節(jié)點一般為目錄,終點節(jié)點可以為目錄或文件。節(jié)點和節(jié)點之間用“/”分開。絕對路徑絕對路徑是指從“根目錄”開始到達某個節(jié)點的路徑,也稱為完全路徑。相對路徑相對路徑是從某節(jié)點開始到其子節(jié)點的路徑。Linux下的用戶Linux是多用戶操作系統(tǒng),多個用戶可以同時登錄進行操作。超級用戶指的是root用戶,它是Linux默認的系統(tǒng)管理員,擁有管理計算機的全部權(quán)限。普通用戶指的是權(quán)限受限的其它用戶。Linux系統(tǒng)中,每個文件、目錄和進程,都歸屬于某一個用戶。通常而言,每個普通用戶只能操作屬于自己的文件、目錄和進程,操作其他用戶的文件、目錄和進程需要得到別的用戶的許可。例:顯示文件的詳細信息后,可以看到Linux下文件的權(quán)限、用戶的對應(yīng)關(guān)系

2408949-rwxr-xr-x1rootroot704-2112:47lsfile.sh

2408260drwxr-xr-x2rootroot4.0K04-2122:15mydir/02常用Shell命令目錄和文件操作命令目錄和文件操作命令改變目錄:cdcd(ChangeDirectory)命令用于在Linux文件系統(tǒng)的不同目錄之間切換。列出目錄內(nèi)容:lsls命令是list的簡化形式,ls的命令選項非常多,下邊只討論一些最常用的選項。-a:顯示所有文件及目錄;-l:除文件名稱外,亦將文件類型、權(quán)限、擁有者、文件大小等信息詳細列出;-r:將文件以相反次序顯示(原定依英文字母次序);-t:將文件依建立時間之先后次序列出;-i:顯示文件的inode號;-A:同-a,但不列出"."(當前目錄)及".."(父目錄);-F:在列出的文件名稱后加一符號,指示文件類型;例如可執(zhí)行文件則加"*",目錄則加"/",鏈接文件后加"@"。2408949-rwxr-xr-x1rootroot704-2112:47lsfile.sh

第一字段:inode(索引節(jié)點)

第二字段:文件種類(-)和權(quán)限(rwx,共9位,分別控制文件屬主、用戶組以及其它用戶的權(quán)限);

第三字段:硬鏈接個數(shù);

第四字段:屬主;

第五字段:所歸屬的組;

第六字段:文件或目錄的大小(字節(jié));

第七字段和第八字段:最后訪問或修改時間;

第九字段:文件名或目錄名文件類型:-:常規(guī)文件d:目錄l:鏈接文件b:塊特殊設(shè)備c:字符特殊設(shè)備目錄和文件操作命令顯示當前目錄:pwdpwd(PrintWorkDirectory)命令會顯示當前所在的位置,即工作目錄。創(chuàng)建和刪除目錄:mkdir和rmdirmkdir:創(chuàng)建一個或多個目錄。rmdir:刪除一個或多個空目錄。目錄必須是空目錄,否則會指出這不是一個空目錄,刪除失敗。復制文件或目錄:cpcp[選項]源文件目標文件cp[選項]源文件組目標目錄目錄和文件操作命令移動或更名:mvmv[-f][-i]文件1文件2 #文件1是源文件,改名操作mv[-f][-i]目錄1目錄2 #目錄1是源目錄,移動目錄操作mv[-f][-i]文件列表目錄

#移動一組文件到目標目錄下刪除文件:rmrm[選項]文件列表rm-rf* #遞歸刪除當前目錄下的所有文件和子目錄目錄和文件操作命令創(chuàng)建鏈接:lnln[選項]目標[鏈接名]ln[選項]目標目錄ln命令用于在文件之間創(chuàng)建鏈接,實際上是給系統(tǒng)中已有的某個文件指定另一個可用于訪問它的名稱。默認情況下,ln產(chǎn)生的是硬鏈接,若需要創(chuàng)建軟鏈接則用參數(shù)-s。鏈接文件鏈接是一種在共享文件和訪問它的用戶的若干目錄項之間建立聯(lián)系的一種方法。對一個目錄下的該文件進行修改,就可以完成對所有目錄下同名鏈接文件的修改。對某個文件的各鏈接文件,可以給它們指定不同的權(quán)限,以控制對信息的共享和增強安全性。文件的鏈接有兩種形式:硬鏈接和符號鏈接(軟鏈接)。硬鏈接:硬鏈接是文件的一個拷貝,其i節(jié)點號是一樣的。但比復制有優(yōu)勢,復制只是一個簡單的拷貝,是靜態(tài)的;而硬鏈接不但是拷貝,而且是動態(tài)和資源共享的。不能對目錄文件創(chuàng)建硬鏈接(root用戶除外);不能在不同的文件系統(tǒng)之間做硬鏈接。軟鏈接:符號鏈接也稱軟鏈接,是一個新文件。符號鏈接類似于windows的快捷方式,符號鏈接實際上是特殊文件的一種。在符號鏈接中,文件實際上是一個文本文件,其中包含有另一個文件的位置信息。硬鏈接和軟鏈接的區(qū)別符號鏈接是一個新文件,具有自己的I節(jié)點號;硬鏈接沒有建立新文件,其只是一個指針。符號鏈接沒有硬鏈接的限制,可以對目錄文件建立符號鏈接,也可以在不同文件系統(tǒng)之間建立符號鏈接。當源文件被刪除后,硬鏈接文件同樣可以被使用,而符號鏈接文件將無法使用。符號鏈接會顯示為“鏈接文件名->指向的實際文件”,而硬鏈接通過文件名無法判斷。例:硬鏈接和軟鏈接具體實例。

$ls-lie1.sh #顯示e1.sh文件的具體信息 403542-rw-r--r--1hllhll602019-11-0401:05e1.sh$lne1.she1_hard.sh #給e1.sh創(chuàng)建一個硬鏈接文件e1_hard.sh$ln-se1.she1_soft.sh #給e1.sh創(chuàng)建一個軟鏈接文件e1_soft.sh$ls-lie1* #顯示e1*文件的具體信息 403542-rw-r--r--2hllhll602019-11-0401:05e1_hard.sh 403542-rw-r--r--2hllhll602019-11-0401:05e1.sh 403553lrwxrwxrwx1hllhll52019-11-1104:14e1_soft.sh->e1.sh$cate1_soft.sh #顯示e1_soft.sh文件內(nèi)容 ThisisthesourcefileoftheHardlinkfileorSoftlinkfile.$cate1_hard.sh #顯示e1_hard.sh文件內(nèi)容 ThisisthesourcefileoftheHardlinkfileorSoftlinkfile.目錄和文件操作命令修改文件權(quán)限:chmod該命令用于改變文件的訪問許可,但是符號鏈接除外chmod[選項]文件和目錄列表設(shè)置權(quán)限的兩種方式:使用字符串設(shè)置權(quán)限使用八進制數(shù)設(shè)置權(quán)限用戶類型包括:屬主用戶user

組用戶(即文件屬主用戶所在的組)group

其它用戶other許可類型包括:

讀read,r寫write,w

執(zhí)行execute,x使用字符串設(shè)置權(quán)限chmodu+re1.sh#給用戶設(shè)置文件e1.sh的r權(quán)限chmodugo+rwe1.sh#給用戶、同組用戶、其他用戶設(shè)置文件e1.sh的rw權(quán)限用戶類型:u表示“用戶(user)”g表示“同組(group)用戶”

o表示“其他(others)用戶”

a表示“所有(all)用戶”chmod用戶類型+/-許可的種類使用八進制數(shù)設(shè)置權(quán)限執(zhí)行權(quán)、寫權(quán)和讀權(quán)所對應(yīng)的數(shù)值分別是1,2和4??梢杂眠@幾位數(shù)進行任意組合,例如:若要rwx屬性則4+2+1=7;

若要rw-屬性則4+2=6;

若要r-x屬性則4+1=5。chmod4e1.sh #給用戶設(shè)置了文件e1.sh的r權(quán)限chmod666e1.sh #給用戶、同組用戶、其他用戶設(shè)置了文件exa2-4的rw權(quán)限目錄和文件操作命令

chattr[-RV][+-=acdijsuADS]文件或目錄名+表示增加某項屬性,-表示取消某項屬性,=設(shè)置文件或目錄只具有哪些屬性;

-R遞歸設(shè)置指定目錄及其目錄下的所有文件和子目錄的屬性;

-V詳細顯示目錄和文件的屬性設(shè)置情況。

a屬性:只允許向文件追加數(shù)據(jù),不允許任何進程覆蓋重寫文件的內(nèi)容。

A屬性:設(shè)置不允許系統(tǒng)更新文件的最后訪問時間

i屬性:不可修改屬性。具有該屬性的文件不能被刪除、更名或修改其內(nèi)容。10.設(shè)置文件的擴展屬性chattr

c屬性:壓縮屬性,寫入或讀取時,系統(tǒng)會自動進行壓縮或解壓縮。

s屬性:安全刪除屬性。即在刪除一個文件時,會使用0填充原文件所在的存貯區(qū),以使恢復工具無法恢復出文件的內(nèi)容。

u屬性:可恢復性的刪除。對于具有該屬性的文件,在刪除時,系統(tǒng)會保留其數(shù)據(jù)塊以便以后能恢復該文件的內(nèi)容例如:若要給/etc/rc.local文件增加不可修改屬性,則實現(xiàn)命令為:chattr+i/etc/rc.local若要取消i屬性,則實現(xiàn)命令為:chattr-i/etc/rc.local查看文件的擴展屬性lsattr查看文件的擴展屬性使用lsattr命令,命令用法:

lsattr[-adR]文件名或目錄名

-a 列出目錄中的所有文件(包括隱藏文件)。

-d 以與文件相同的方式列出目錄的擴展屬性。

-R 以遞歸的方式列出目錄的屬性及其內(nèi)容。例如,若將/etc/rc.local文件設(shè)置為具有i屬性和A屬性,并查看設(shè)置后的屬性,其實現(xiàn)命令為:

[root@RHEL5~]#chattr=iA/etc/rc.local

[root@RHEL5~]#lsattr/etc/rc.local

----i--A-----/etc/rc.local用戶管理命令用戶管理命令添加用戶命令:useradd修改用戶密碼:passwduseradd[選項]用戶名passwd[選項]用戶名$useraddjack#創(chuàng)建的是“三無”用戶,無家目錄,無密碼,無系統(tǒng)Shell$grepjack/etc/passwd#查看jack用戶信息 jack:x:1003:1003::/home/jack:/bin/sh#顯示jack用戶創(chuàng)建成功$ls/home yybhll #但是,在home目錄下無jack家目錄$useradd-m-s/bin/bash-d/home/jack1jack1$passwdjack#修改用戶jack的密碼 EnternewUNIXpassword:#輸入密碼時,屏幕不會顯示任何信息 RetypenewUNIXpassword: passwd:passwordupdatedsuccessfully用戶管理命令修改用戶信息:usermod修改用戶密碼狀態(tài):chageusermod[選項]用戶名chage[選項]用戶名$grepjack/etc/passwd#查看修改前的用戶信息jack:x:1001:1001::/home/jack:#usermod-lmikejack#grepmike/etc/passwd#查看修改后的用戶信息mike:x:1001:1001::/home/jack:#chage-ljackLastpasswordchange :Nov11,2019Passwordexpires

:neverPasswordinactive :neverAccountexpires :neverMinimumnumberofdaysbetweenpasswordchange :0Maximumnumberofdaysbetweenpasswordchange :99999Numberofdaysofwarningbeforepasswordexpires :7用戶管理命令刪除用戶命令:userdel查看用戶id命令:id刪除系統(tǒng)中已有的用戶,該命令的格式如下:userdel[選項]用戶名查看系統(tǒng)中指定用戶的id,該命令的格式如下:id用戶名用戶管理命令切換用戶身份命令:su顯示系統(tǒng)登錄用戶:whosu[選項]用戶名-:只使用“-”代表連帶用戶的環(huán)境變量一起切換-c:僅執(zhí)行一次命令,但不切換用戶身份who命令顯示關(guān)于當前在本地系統(tǒng)上的所有用戶的信息。顯示以下內(nèi)容:登錄名、終端類型(tty)、登錄日期和時間。通過su命令,可以從普通用戶切換到root用戶,也可以從root用戶切換到普通用戶。從普通用戶切換到root用戶需要密碼,從root用戶切換到普通用戶不需要密碼。Linux還提供另一個與su相關(guān)的命令,即sudo命令。sudo可以跳過root用戶登錄而去執(zhí)行一些特定命令。$sudopasswdjack#更改jack用戶的密碼當然,這條命令執(zhí)行的前提是當前登錄用戶擁有執(zhí)行sudo命令的權(quán)限,這可以通過配置/etc/sudoers文件來實現(xiàn)。其他常用命令其他常用命令1.find:查找文件或目錄格式:find[目錄列表][匹配標準]參數(shù)說明:目錄列表:希望查詢文件或文件集的目錄列表,目錄間用空格分隔。匹配標準:希望查詢的文件的匹配標準或說明。隨著文件的增多,使用搜索工具成了順理成章的事情。find就是這樣一個強大的命令,它能夠迅速在指定范圍內(nèi)查找到文件,命令格式為:-name文件告訴find要找什么文件;要找的文件包括在引號中,可以使用通配符(*和?)

-perm模式匹配所有模式為指定數(shù)字型模式值的文件。不僅僅是讀,寫和執(zhí)行,所有模式都必須匹配。如果在模式前是負號(-),表示采用除這個模式外的所有模式。

-typex匹配所有類型為x的文件。x是c(字符特殊),b(塊特殊),d(目錄),p(有名管道),l(符號連接),s(套接文件)……-linksn匹配所有連接數(shù)為n的文件。

-user用戶號匹配所有用戶序列號是前面所指定的用戶序列號的文件,可以是數(shù)字型的值或用戶登錄名。

-atime+/-n匹配所有在n天前/n天內(nèi)訪問過的文件。-mtime+/-n匹配所有在n天前/n天內(nèi)修改過的文件。

-newer文件匹配所有修改時間比file文件更新的文件。

-sizen匹配所有大小小于n塊的文件(若k在n后,則為1K字節(jié)塊),1塊=512字節(jié)。

-print顯示整個文件路徑和名稱。一般來說,都要用-print,如果沒有這個參數(shù),則find命令進行所要求的搜索是沒有顯示結(jié)果的。

其它常用命令34通過文件名查找

#find/root-namehttpd.conf–print2)根據(jù)部分文件名查找 #find/root–name‘*http*’-print3)根據(jù)文件的特征查詢

#find/etc-size+10-size12-print$find/home/-namedays-print/home/hll/prac/daysfind:‘/home/hll/.dbus’:Permissiondeniedfind:‘/home/hll/.cache/dconf’:Permissiondenied在find文件時,如果用到通配符,需要用單引號括起來。$

find/home/yyb‘e*.sh’$find/home/yyb‘e[234].sh’其他常用命令查找文件內(nèi)容:grep在很多時候,并不需要列出文件的全部內(nèi)容,用戶要做的只是找到包含某些信息的一行。這個時候,如果使用more命令一行一行去找的話,無疑很浪費精力。當文件內(nèi)容特別多的時候,這樣的做法則完全不可行了。為了在文件中尋找某些信息,可以使用grep命令$grepundaysweatherdays:Sundayweather:sunny#在文件days和weather里面找有字符串un的行其他常用命令less、more和cat命令都是用于查看文本文件內(nèi)容,但less的功能更為強大。less改進了cat、more命令的很多細節(jié),并添加了許多的特性,這些特性讓less看起來更像是一個文本編輯器——只是去掉了文本編輯功能。分屏查看文件內(nèi)容:lessless在屏幕底部顯示一個冒號“:”等待用戶輸入命令。如果想向下翻一頁,可以按下空格鍵,如果想向上翻一頁,按下B鍵。也可以用光標鍵向前、后、甚至左右移動。如果要在文件中搜索某一個字符串,可以使用“/”加想要查找的內(nèi)容,less會把找到的第一個搜索目標高亮顯示,要繼續(xù)查找相同的內(nèi)容,只要再次輸入“/”,并按下回車鍵。最后,按下Q鍵可以退出less程序并返回Shell提示符。其他常用命令date命令可以用來顯示或設(shè)定系統(tǒng)的日期與時間。在顯示方面,使用者可以自行設(shè)定時間顯示格式,格式設(shè)定為一個加號后接數(shù)個標記。若是不以加號作為開頭,則表示要設(shè)定時間。時間格式為:MMDDhhmm[YYYY][.ss]。其中

MM為月份,DD為日,hh為小時,mm為分鐘,YYYY為年份,ss為秒數(shù)。顯示系統(tǒng)時間:date$date #顯示系統(tǒng)時間TueNov1200:38:25PST2019$date111216462019.30 #設(shè)置系統(tǒng)完整時間TueNov1216:46:30PST2019$date-s1651 #設(shè)置系統(tǒng)的時、分TueNov1216:51:00PST2019其他常用命令ps命令是processstatus的縮寫,用于顯示當前進程的狀態(tài)。使用該命令可以確定有哪些進程正在運行和運行的狀態(tài)、進程是否結(jié)束、進程有沒有僵死、哪些進程占用了過多的資源等等。kill命令用來終止指定的進程的運行。通常,終止一個前臺進程可以使用Ctrl+C鍵,但是,對于一個后臺進程就須用kill命令來終止。顯示進程命令:ps關(guān)閉進程命令:killkill[參數(shù)][進程號]$ps-ef|grepvimroot32682884016:21pts/100:00:00viminstall.logroot33702822016:21pts/000:00:00grepvim$kill3268$kill3268-bash:kill:(3268)-Nosuchprocess#連續(xù)關(guān)閉進程3268,第2次提示錯誤其他常用命令init是Linux系統(tǒng)操作中不可缺少的程序之一。init進程,它是一個由內(nèi)核啟動的用戶級進程,然后由它來啟動后面的任務(wù),包括多用戶環(huán)境,網(wǎng)絡(luò)等。init命令很簡單,直接輸入init+模式對應(yīng)的編號。shutdown是系統(tǒng)關(guān)機命令,也可以用于關(guān)閉所有程序,并依用戶的需要,進行重新開機或關(guān)機的動作。shutdown命令執(zhí)行后,會以廣播的形式通知正在系統(tǒng)中工作的所有用戶,系統(tǒng)將在指定的時間內(nèi)關(guān)閉。Init命令關(guān)機命令:shutdowninit0#停機 init1#單用戶模式,只root用戶進行維護init2#多用戶模式,不能使用NFSinit3#完全多用戶模式(標準的運行級)init4#安全模式init5#切換到圖形化界面init6#重新啟動shutdown常用參數(shù)有:-tseconds:設(shè)定在幾秒鐘之后進行關(guān)機程序;-k:將警告訊息傳送給所有使用者;-r:關(guān)機后重新開機;-h:關(guān)機后停機;time:設(shè)定關(guān)機的時間。其他常用命令zip命令用于壓縮文件,unzip命令用于解壓文件。tar是Linux環(huán)境下最常用的備份工具之一,它可用于建立、還原、查看、管理文件,也可方便的追加新文件到備份文件中,或僅更新部分的備份文件,以及解壓、刪除指定的文件。熟悉其常用參數(shù),能方便日常的系統(tǒng)管理工作。文件壓縮命令:zip打包與解包:tarwww.islide.cc41常用選項意義-A將文檔與已有的文檔合并-c建立新的文檔-d比較文檔與當前文件的不同之處--delete從文檔中刪除-f使用檔名,請留意,在f之后要立即接檔名-t列出文檔中文件的目錄-v壓縮的過程中顯示文件

-x從文檔展開文件-C轉(zhuǎn)到指定的目錄-k保存現(xiàn)有文件;從文檔中展開時不進行覆蓋-m當從一個文檔中恢復文件時,不使用新的時間標簽-z用gzip

對文檔壓縮或解壓www.islide.cc42$tar-cvftest.tar./Scripts/#將Scripts子目錄下的所有文件打包成test.tar$tar-jcvftest.tar.zip2./Scripts/#將Scripts子目錄下的所有文件打包并使用

bzip2壓縮,得到test.tar.zip2文件$tar-jxvftest.tar.zip2-C/home/hll#將test.tar.zip2解包到/home/hll目錄下$tar-tftest.tar.zip2#顯示test.tar.zip2包中的文件和目錄tar使用舉例其他常用命令Linux提供了豐富的幫助手冊,當需要查看某個命令的參數(shù)時不必到處上網(wǎng)查找,只要man一下即可。此外,man還可以用于查詢系統(tǒng)庫文件中的一些函數(shù)定義和使用方法。man基本用法如下:whereis命令主要用于查找程序文件,并提供這個文件的二進制可執(zhí)行文件、源代碼文件和使用手冊頁存放的位置。常用參數(shù)包括-b、-m和-s,分別對應(yīng)查找二進制可執(zhí)行文件、使用手冊和源代碼文件。此外,也可以通過-B、-M和-S等參數(shù)在指定目錄下查找對應(yīng)文件。獲得幫助命令:man查找特定程序:whereisman[參數(shù)][命令]。 #詳細的命令用法命令–help #簡單的命令用法命令行高級技巧Tab鍵自動補齊文件名是命令中最常見的參數(shù),然而每次完整輸入文件名是一件很麻煩的事情,特別是當文件名特別長的時候。所以,bash提供了這樣一種特性——命令行補全。在輸入文件名的時候,只需要輸入前面幾個字符,然后按下Tab鍵,Shell會自動把文件名補全。如果以所鍵入的字符開頭的文件不止一個,那么可以連續(xù)按下Tab鍵兩次,Shell會以列表的形式給出所有以鍵入字符開頭的文件。

命令行高級技巧通配符使用Shell有一套被稱作通配符的專用符號,分別是*、?、[]。這些通配符可以搜索并匹配文件名的一部分,從而大大簡化了命令的輸入。也可以使用短線“-”來指定一個字符集范圍。所有包括在上下界之間的字符都會被匹配?!?”用于匹配文件名中任意長度的字符串。和“*”類似的通配符是“?”。但和“*”匹配任意長度的字符串不同,“?”只匹配一個字符?!癧]”用于匹配所有出現(xiàn)在方括號內(nèi)的字符命令行高級技巧重定向a)輸出重定向符>、>>“<<”為此處操作符,該操作符在從鍵盤讀取內(nèi)容時,讀到指定的字符串時,便停止讀取動作,然后將所讀的內(nèi)容輸出。

“<”標準輸入重定向符用于改變一個命令的輸入源。>和>>的區(qū)別在于:>重定向符每次都是以覆蓋的方式重寫后面的文件內(nèi)容,若指定的文件不存在,系統(tǒng)會自動創(chuàng)建。若要將內(nèi)容以追加的方式添加到后面的文件中,則應(yīng)采用>>重定向符。輸出重定向符能實現(xiàn)將一個命令的輸出重定向到一個文件中。b)輸入重定向符<、<<

cat<<end>file.txt命令行高級技巧組合命令組合命令的基本方法是采用命令棧的形式。所謂命令棧,就是將所有需要運行的命令放到Shell的一行上,再用分號“;”隔開每個命令。接著依次順序執(zhí)行每個命令,只有一個命令結(jié)束運行(無論成功與失?。┖螅艜\行下一個命令。$cdEmbedded;ls-l;mkdirScript;mv*.shScript分割命令的另一個辦法是用&&。它同樣是依次執(zhí)行每個命令,但只有當前面一條指令運行成功后,才能執(zhí)行下一條指令。如果前面命令運行失敗,后續(xù)命令都不會被執(zhí)行。$mv*.sh..&&cd..&&rm–rfScript&&ls-l命令行高級技巧48使用“$()”可將一個命令的輸出插入到另一個命令,這就是所謂的命令替換。$ls #顯示當前目錄內(nèi)容

#無內(nèi)容,空目錄$mkdir$(date"+%Y-%m-%d")&&ls #創(chuàng)建目錄并顯示目錄內(nèi)容2019-10-20 #有一個以日期命名的目錄使用“|”可以將一個命令的輸出作用于另一個命令的輸入。$ls-l|grepconf|less

上例中,先將ls命令的結(jié)果輸入給grep命令,實現(xiàn)查找文件名中含conf的文件的目的;然后將grep命令的結(jié)果輸入給less命令,實現(xiàn)分屏顯示。/03Shell編程基礎(chǔ)Shell腳本的執(zhí)行Shell腳本本質(zhì)上只是普通文本文件,由bash對其進行解釋執(zhí)行。因此,凡是可以在bash提示符后輸入的命令,都可以出現(xiàn)在腳本文件里。Shell腳本執(zhí)行有三種方法:標準方法將下列文本加到腳本文件的頂端(第一行靠左對齊):#!/bin/bash然后通過下面命令改變文件訪問模式,使其成為可執(zhí)行文件(這里假設(shè)腳本名為myscript):$chmod+xmyscript$./myscriptShell腳本的執(zhí)行用bash命令執(zhí)行腳本用source命令執(zhí)行腳本對于會影響shell環(huán)境的腳本,應(yīng)該交給當前的shell,即loginshell去運行。此時執(zhí)行方式為“source腳本名”或“.腳本名”的方式。$sourcemyscriptbash會將它的參數(shù)視為腳本文件的名稱,并予以運行。$bashmyscript

采用第3種方式,腳本中的變量會添加到當前登錄用戶的環(huán)境變量中。Shell腳本的輸入輸出輸入用read命令來實現(xiàn),它每次從stdin(標準輸入,一般指鍵盤)讀入一行數(shù)據(jù),并將其存入一個變量中。具體來說,read命令用于一個一個詞組地接收輸入的參數(shù),每個詞組需要使用空格進行分隔;如果輸入的詞組個數(shù)大于需要的參數(shù)個數(shù)(如變量的個數(shù)),則多出的詞組將被作為整體為最后一個參數(shù)接收。由printf和echo命令來實現(xiàn),這兩個命令的功能基本類似,都可以用于字符串或變量的輸出,默認輸出設(shè)備都是stdout(標準輸出,一般指屏幕)。使用printf的腳本比使用echo移植性更好。在進行輸出時,printf和echo最大的不同在于printf不像echo那樣會自動提供一個換行符號,必須顯式地將換行符號指定成“\n”。輸出Shell變量變量命名Shell變量命名必須遵循如下規(guī)則:命名只能使用英語字母,數(shù)字和下劃線,首字符不能以數(shù)字開頭;中間不能有空格,可以使用下劃線“_”;不能使用標點符號;不能使用bash里的關(guān)鍵字(可用help命令查看保留關(guān)鍵字)。Shell變量變量賦值在Shell編程中,通常情況下變量并不需要專門的定義和初始化。一個沒有初始化的Shell變量被認為是一個空字符串。用戶可以通過變量的賦值操作來完成變量的聲明并賦予一個特定的值,也可以通過賦值語句為一個變量多次賦值,以改變其值。默認為字符串變量。在Shell中,變量的賦值使用以下語法:v_name=value。其中,v_name表示變量名,value表示將要賦給變量的值;中間的等號“=”稱為賦值符號,賦值符號的左右兩邊不能直接跟空格,否則Shell會將其視為命令。

Shell變量變量引用當變量賦值完成之后,就需要使用變量的值。在Shell中,用戶可以通過在變量名前加上“$變量名”或“${變量名}”來獲取該變量的值。實際上,在前面的許多例子中,已經(jīng)多次使用這個符號來獲取變量的值。通常情況下,“$變量名”或“${變量名}”沒有差別。但是,當在一串字符串中引用變量構(gòu)成新的字符串時,建議采用“${變量名}”這種方法進行變量引用。$Str1=“Hello”$Str2=$Str1World!$Str2=${Str1}World!Shell變量除用$符號引用變量外,在Shell腳本中也經(jīng)常用到其它4種引用符號,這些引用符號的作用如下表所示。假設(shè)變量x1=Windows,則下面命令執(zhí)行結(jié)果如下:$echo"${x1}10"Windows10

$echo'${x1}10'${x1}10$echo\'${x1}10\''Windows10'$echo`pwd`/home/hllShell變量變量作用域與其它程序設(shè)計語言一樣,Shell中的變量也分為全局變量和局部變量兩種。下面分別介紹這兩種變量的作用域。(1)全局變量(2)局部變量Shell編程中,全局變量可以在腳本中定義,也可以在某個函數(shù)中定義。實際上,只要不是用local關(guān)鍵字定義的變量,都可以視為全局變量,其作用域為從被定義的地方開始,一直到Shell腳本結(jié)束或者被顯示地刪除。局部變量通常僅限于某個程序段訪問,例如函數(shù)內(nèi)部。在Shell編程中,可以在函數(shù)內(nèi)部通過local關(guān)鍵字來定義局部變量。另外,函數(shù)的參數(shù)也是局部變量。Shell變量www.islide.cc58#!/bin/bashfunc() #定義函數(shù){ echo"$x" #輸出變量x的值 x=10 #修改變量x的值}x=20 #在腳本中定義變量xfunc #調(diào)用函數(shù)echo"$x" #輸出變量x的值1. #!/bin/bash2. func() #定義函數(shù)3. {4. echo"$x" #輸出變量x的值5. localx=10 #定義局部變量x6. echo"$x" #輸出變量x的值7. }8. x=20 #在腳本中定義變量x9. func #調(diào)用函數(shù)10. echo"$x" #輸出變量x的值Shell變量默認變量不需要用戶定義,可以直接使用的變量,包括環(huán)境變量和自動變量。(1)環(huán)境變量(2)自動變量環(huán)境變量用于用戶登錄系統(tǒng)時建立Shell運行環(huán)境,它由一系列環(huán)境變量及其值組成。運行環(huán)境包括用戶Home目錄、系統(tǒng)提示符、用戶名、搜索路徑等。

自動變量由Shell自動根據(jù)上下文環(huán)境確定其值,用戶只能引用這些變量,不能對其值進行重新設(shè)置。Shell變量www.islide.cc60常用環(huán)境變量常用自動變量算術(shù)運算算術(shù)運算符Shell中的算術(shù)運算符主要包括加、減、乘、除、求余,以及冪運算等。下表列出了常用的基本算術(shù)運算符及其使用方法。算術(shù)運算算術(shù)運算命令雖然Shell支持算術(shù)運算,但不能直接使用上表中的符號,需要配合下面的命令才能完成算術(shù)運算。expr命令let命令語法格式:exprexpression。運算符左右要有空格語法格式:letvar=expression。運算符兩邊不能有空格1. #!/bin/bash2. letm=23. letn=184. echo"m=$m,n=$n"5. echo'exprm+n='`expr$m+$n`6. echo'exprn%m='`expr$n%$m`7. echo'exprm-n='`expr$m-$n`8. echo'exprm/n='`expr$m/$n`9. letx=$m+$n10. echo"letm+n=$x"11. letx=$n%$m12. echo"letn%m=$x"13. #end算術(shù)運算位運算所謂位運算,即對變量每個位進行操作。BashShell支持的位運算符如下表所示。語法格式:$[expression]或let"expression"。算術(shù)運算641. #!/bin/bash2. letm=23. letn=44. echo"m=$m,n=$n"5. echo"leftshift,n<<m="$[$n<<$m] #位運算符兩邊有空格6. echo"rightshift,n>>m="$[$n>>$m]7. echo"and,n&m="$[$n&$m] #位運算符兩邊無空格8. echo"or,n|m="$[$n|$m]9. echo"not,~n="$[~$n]條件測試條件測試的基本語法條件測試包括test命令和[]命令。條件測試的語法:testexpression或[expression]。其中,參數(shù)expression表示需要進行測試的條件表達式,可以由字符串、整數(shù)、文件名,以及各種運算符組成。在使用[expression]進行條件測試時,條件表達式與左右方括號之間都必須有一個空格。條件測試字符串測試在任何程序設(shè)計語言中,字符串都是最常見的數(shù)據(jù)類型之一。在Shell中,用戶可以通過5種運算符來對字符串進行條件測試操作,如下表所示。條件測試str1="abc"str2="cba" #可以在同一行中定義兩個變量echo"str1=$str1,str2=$str2"test$str1

#測試變量str1是否非空echo$? #顯示上條測試命令的結(jié)果,0為真,1為假test$str1=$str2

#測試字符串相等,等號兩邊有空格echo$?test$str1="abc" #測試變量str1是否等于abcecho$?[-z$str1]

#測試變量str1是否為空串echo$?[-n$str1]

#測試變量str1是否為非空串echo$?條件測試整數(shù)測試整數(shù)測試的語法:testnum1opnum2或者[num1opnum2]。其中,num1和num2分別表示參與比較的兩個整數(shù),可以是常量或者變量,op表示條件運算符,常用整數(shù)測試的條件運算符如表所示。letv1=2v2=4echo"v1=$v1,v2=$v2"test$v1-eq$v2echo$?[$v1-ne$v2]echo$?test$v1-gt$v2echo$?[$v1-lt$v2]echo$?test$v1-ge$v2echo$?[$v1-le$v2]echo$?條件測試文件測試語法格式:testopfile或者[opfile]在上面的語法中,op表示文件條件測試運算符,file為測試文件名。常用的文件條件測試運算符如右表所示。$test-ee6.sh$[-re1.sh]

條件測試邏輯測試在Shell編程中,經(jīng)常遇到同時判斷多個條件是否成立或部分成立的情況,此時,就可以利用Shell的邏輯運算符將多個不同的條件組合起來,從而構(gòu)成一個復雜的條件表達式。常用的邏輯運算符如表所示。$test"$x"-gt20-a"$x"-lt30

#判斷20<x<30是否成立$[-eexam-1-a-wexam-1] #判斷文件exam-1是否存在且可寫/04Shell編程的控制語句條件判斷語句if結(jié)構(gòu)條件判斷語句使用if結(jié)構(gòu)來實現(xiàn),其結(jié)構(gòu)如下:在上面的語法中,expression通常代表測試某個條件,但是也可以是Shell命令。ifexpressionthen

statement......fiifexpression1thenstatement...elifexpressionthenstatement

...elsestatement...fi73通過if-elif-else結(jié)構(gòu),將學生的百分制成績轉(zhuǎn)換成優(yōu)(≥85)、通過(60-85之間)、不通過(<60),代碼如下:#!/bin/bashecho"Pleaseenterascore:" #輸出提示信息readscore #讀取用戶輸入數(shù)據(jù)if[-z"$score"] #如果用戶沒有輸入數(shù)據(jù),提示錯誤thenecho"Youenternothing.Error!"elif["$score"-lt0-o"$score"-gt100]#如果分數(shù)不在0-100,提示錯誤thenecho"Youenterwrongdata.Error!"elif["$score"-ge85] #如果≥85分,提示優(yōu)秀thenecho"Congratulation.Thegradeisexcellent!"elif["$score"-ge60] #如果在60-85之間,提示通過thenecho"Youpassedinthistest."else

#如果小于60分,提示未通過echo"Sorry,youfailedinthistest."fi多條件判斷語句2.case結(jié)構(gòu),實現(xiàn)多條件判斷在左面的語法中,variable是一個變量,case語句會將該變量的值與value1~valueN中的每一個值相比較,如果與某個value的值相等,則執(zhí)行該value所對應(yīng)的一組語句。當遇到“;;”符號時,就跳出case語句,執(zhí)行esac語句后面的語句。對于變量名variable,可以使用雙引號,也可以不使用。每個case子句中的條件測試部分,都以右括號“)”結(jié)束。每個case子句都以一對分號“;;”作為結(jié)束符。casevariableinvalue1) statement-body-1 ;;value2) statement-body-2 ;;…valueN) statement-body-N ;;*) statement-body-N+1 ;;esac通過case結(jié)構(gòu),判斷用戶輸入的4種字符類型,代碼如下:75#!/bin/bashecho"Hitakey,thenhittheenterkey." #提示輸出信息readkeypress #讀取用戶按下的鍵case"$keypress"in #case語句開始

[[:lower:]]) #小寫字母,涉及了正則表達式的內(nèi)容echo"Lowercaseletter.";;[[:upper:]]) #大寫字母echo"Uppercaseletter.";;[0-9]) #單個數(shù)字echo"Digit.";;*) #*代表缺省條件,這里代表其他字符echo"otherletter.";;esac循環(huán)結(jié)構(gòu)3.for循環(huán)結(jié)構(gòu)在上面的語法中,variable稱為循環(huán)變量,in后面是變量取值。do和done之間的所有的語句稱為循環(huán)體,即循環(huán)結(jié)構(gòu)中重復執(zhí)行的語句。forvariablein{list}dostatement...doneforvariablein{start..end..step}dostatement...doneforvariablein${array[*]}dostatement...done采用for循環(huán)結(jié)構(gòu),找出數(shù)組的元素個數(shù)及最小值。77#!/bin/basharray=(1-47-82034) #Shell中,用()來定義數(shù)組letn=0forvarin${array[*]} #對數(shù)組中的每個元素doif[$n-eq0] #初始值設(shè)為數(shù)組的第一個值thenletmin=$varelseif[$var-lt$min] #如果比已知的最小值還小,保存新的最小值thenmin=$varfifiletn=n+1 #處理序號doneecho"Theminvalueinthearrayis$min."echo"Thenumberofelementsinthearrayis$n."循環(huán)結(jié)構(gòu)4.while循環(huán)結(jié)構(gòu)while循環(huán)結(jié)構(gòu)的格式如下:在上面的語法中,expression表示while循環(huán)體執(zhí)行時需要滿足的條件,do和done這兩個關(guān)鍵字之間的語句構(gòu)成了循環(huán)體。當while循環(huán)結(jié)構(gòu)在執(zhí)行時,會首先計算expression表達式的值,如果表達式的值為0,則執(zhí)行循環(huán)體中的語句;否則,退出while循環(huán),執(zhí)行done關(guān)鍵字后面的語句。當循環(huán)體中的語句執(zhí)行完成之后,會重新計算expression的值,如果仍然是0,則繼續(xù)執(zhí)行下一次的循環(huán),直至expression的值為非0。whileexpressiondostatement...done采用while循環(huán)結(jié)構(gòu),實現(xiàn)猜數(shù)字的游戲。79#!/bin/bashletcorrect=75n=1echo"Pleaseenteranumberbetween1and100."#提示用戶輸入數(shù)字readvar #讀取用戶輸入的數(shù)字while[$var-ne$correct] #while循環(huán)開始doif[$var-lt$correct] #提示用戶輸入數(shù)字太小thenecho"Toosmall.Tryagain."readvarelse[$var-gt$correct] #提示用戶輸入數(shù)字太大

echo"Toobig.Tryagain."readvarfiletn=n+1doneecho"Congratulation!Youinputthecorrectnumber$correctin$ntimes."循環(huán)結(jié)構(gòu)5.until循環(huán)結(jié)構(gòu)until循環(huán)的功能是不斷地重復執(zhí)行循環(huán)體中的語句,直至某個條件成立。在上面的語法中,expression是一個條件表達式。當該表達式的值不為0時,將執(zhí)行do和done之間的語句;當expression的值為0時,將退出until循環(huán)結(jié)構(gòu),繼續(xù)執(zhí)行done語句后面的其他語句。實質(zhì)上,until循環(huán)結(jié)構(gòu)和while循環(huán)結(jié)構(gòu)的差別就在于一個是條件為假時執(zhí)行循環(huán)體,一個是條件為真時執(zhí)行循環(huán)體。因此,這兩個循環(huán)結(jié)構(gòu)可以互相轉(zhuǎn)換。untilexpressiondostatement...doneuntil循環(huán)的語法格式如下:循環(huán)結(jié)構(gòu)6.利用break和continue控制循環(huán)在Shell的循環(huán)結(jié)構(gòu)中,break語句與continue語句的作用與C程序設(shè)計中的break與continue的作用完全一樣。具體來說,break用來跳出當前循環(huán),即結(jié)束本層循環(huán)體;continue用來結(jié)束本次循環(huán),因而它的作用不是退出循環(huán)體,而是跳過當前循環(huán)體中該語句后面的語句,重新從循環(huán)語句開始的位置執(zhí)行。此外,在默認情況下,break語句僅僅退出一層循環(huán),如果用戶想要退出多層循環(huán),可以在break語句的后面增加一個數(shù)字作為參數(shù),用來指定要退出的循環(huán)的層數(shù)。比較下面腳本的輸出:82#!/bin/bash #!/bin/bash forxin1234 forxin1234do do

echo"hello" echo"hello"

continue

break

echo"shell" echo"shell"done done嵌入式系統(tǒng)原理與設(shè)計第9章Linux下程序設(shè)計工具第XX章0102030405Vi編輯器GCC編譯器GDB調(diào)試Make項目管理器Makefile編程/01Vi編輯器Vi編輯器圖形界面編輯器的代表是gedit文本界面編輯器的代表是Vi,它沒有采用圖形界面,因而運行效率很高,缺點在于需要記住眾多的命令。Linux下的編輯器可以分為圖形界面編輯器和文本界面編輯器。Vi的啟動與退出啟動:在Linux終端命令提示符下輸入vi(或vi文件名),即可啟動vi編輯器。#vifilename退出:要退出Vi,必須先按“Esc”鍵回到命令行模式,然后輸入“:”,此時光標會停留在最下面一行(底行模式),再輸入“q”,最后按“Enter”鍵即可退出。Vi工作模式Vi工作模式命令行模式:也叫做“普通模式”,它是啟動Vi編輯器后的初始模式。在該模式下主要是使用隱式命令(命令不顯示)來實現(xiàn)光標的移動、復制、粘貼、刪除等操作。在該模式下,編輯器并不接受用戶從鍵盤輸入的任何字符作為文檔的編輯內(nèi)容。插入模式:在該模式下,用戶輸入的任何字符都被認為是編輯到文件中的內(nèi)容,并直接顯示在Vi的文本編輯區(qū)。底行模式:在該模式下,用戶輸入的任何字符都會在Vi的最下面一行顯示,按“Enter”鍵后便會執(zhí)行該命令(當然前提是輸入的命令正確)。Vi使用實例練習參考教材中三種模式的常用命令,編輯源代碼并將其命名為vi_test.c/*vi_test.c*/#include<stdio.h>intmax(inta,intb);main(){inta,b;printf("Enterab:");scanf("%d%d",&a,&b);printf("max=%d\n",max(a,b));}intmax(inta,intb){intp;p=a>b?a:b;return(p);}Vi使用實例練習在編輯完vi_test.c后完成以下操作:(1)為了方便查看代碼,在Vi編輯器中顯示行號(2)將第5-8行的內(nèi)容復制到第8行行首(3)刪除此時光標所在行(4)將源代碼每行的第一個字符“i”替換成字符“n”。(5)撤銷上一步操作/02GCC編譯器GCC編譯器GCC全稱是GNUCCompiler,它是GNU組織推出的符合ANSIC標準的功能強大、性能優(yōu)越的多平臺編譯器。經(jīng)過幾十年的發(fā)展,GCC已經(jīng)成為Linux下最重要的免費軟件開發(fā)工具,它不僅支持C語言,還支持C++語言、Java語言、Objective語言、Ada語言、Pascal語言、COBOL語言等。因此,GCC也被成為GNU編譯器集合。此外,GCC還是一個交叉平臺編譯器GCC編譯器交叉編譯器:在一個CPU平臺上編譯另一個CPU平臺的程序,這兩個CPU平臺的指令體系結(jié)構(gòu)不一樣GCC目前支持所有主流CPU平臺,可以完成從C、C++、Java等源文件向運行在特定CPU硬件平臺上的目標代碼的轉(zhuǎn)換。GCC編譯器所能支持的部分源程序的格式后綴名所對應(yīng)語言后綴名所對應(yīng)語言.cC語言源程序.s/.S匯編語言源程序.C/.cc/.cxxC++源程序.h預處理文件(頭文件).mObjective-C源程序.o目標文件.i已經(jīng)經(jīng)過預處理的C程序.a/.so編譯后的文件.ii已經(jīng)經(jīng)過預處理的C++程序

GCC編譯流程預處理(Pre-Processing)編譯(Compiling)匯編(Assembling)鏈接(Linking)GCC編譯流程下面以一個簡單的“Hello,World”實例程序來說明,/*hello.c*/#include<stdio.h>intmain(){printf("Hello!Thisisourembeddedworld!\n");return0;}return(p);}預處理階段預處理階段主要完成3個功能:1)將源文件中以“#include”格式包含的文件復制到編譯的源文件中;2)用實際值替換用“#define”定義的字符串;3)根據(jù)“#if”后面的條件確定實際需要編譯的源代碼。注:實例代碼中僅需將stdio.h復制到源文件預處理階段GCC中,“-E”選項用來指示僅做預處理,預處理結(jié)束后停止編譯過程。[root@localhostgcc]#gcc–Ehello.c–ohello.i在上面命令中,選項“-o”用來指定輸出的目標文件名稱,“hello.i”為已經(jīng)過預處理的C源程序typedefint(*__gconv_trans_fct)(struct__gconv_step*,struct__gconv_step_data*,void*,__constunsignedchar*,__constunsignedchar**,__constunsignedchar*,unsignedchar**,size_t*);…#2"hello.c"2intmain(){printf("Hello!Thisisourembeddedworld!n");return0;}編譯階段在編譯階段,GCC首先要檢查經(jīng)過預處理后的源代碼的規(guī)范性(是否有語法錯誤等),檢查無誤后再把源代碼翻譯成目標CPU平臺的匯編語言。[root@localhostgcc]#gcc–Shello.i–ohello.sGCC中,“-S”選項用來指示僅做編譯、生成匯編代碼,匯編代碼生成后結(jié)束編譯過程。編譯階段.file"hello.c".section.rodata.align4.LC0:.string"Hello!Thisisourembeddedworld!".text.globlmain.typemain,@functionmain:push1%ebpmovl%esp,%ebpsubl$8,%espandl$-16,%espmovl$0,%eaxaddl$15,%eaxaddl$15,%eaxshrl$4,%eaxsall$4,%eaxsubl%eax,%espsubl$12,%esppushl$.LC0callputsaddl$16,%espmovl$0,%eaxleaveret.sizemain,.-main.ident"GCC:(GNU)4.0.020050519(RedHat4.0.0-8)".section.note.GNU-stack,"",@progbits匯編階段匯編階段是把編譯階段生成的“.s”文件轉(zhuǎn)成目標文件。GCC中,可以使用選項“-c”將匯編代碼轉(zhuǎn)化為以“.o”結(jié)尾的二進制目標代碼。[root@localhostgcc#gcc–chello.s–ohello.o注:由于hello.o為二進制文件,不能用文本編輯器打開;如果用文本編輯器強制打開,顯示為一堆亂碼。鏈接階段上面生成的hello.o并沒有定義“printf”函數(shù)的實現(xiàn),而預編譯中包含進的“stdio.h”中也只有該函數(shù)的聲明,無該函數(shù)的實現(xiàn)。那么,是在哪里實現(xiàn)“printf”函數(shù)的呢?通俗的講,鏈接就是找到函數(shù)的實現(xiàn)處,也就是函數(shù)庫。而函數(shù)庫按時間、空間需求可分為靜態(tài)庫與動態(tài)庫鏈接階段靜態(tài)庫:指編譯鏈接時,把庫文件的代碼全部加入到可執(zhí)行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件,其后綴名一般為“.a”。(“以空間換時間”)動態(tài)庫:在鏈接時并沒有把庫文件的代碼加入到可執(zhí)行文件中,因而生成的文件比較小,但在程序執(zhí)行時需要動態(tài)加載庫文件的代碼,其后綴名一般為“.so”。(“以時間換空間”)鏈接階段在GCC中,“printf”函數(shù)實現(xiàn)被放到名為“l(fā)ibc.so.6”的庫文件中,它是一個動態(tài)庫。在沒有特別指定時,GCC會到系統(tǒng)默認的搜索路徑“/usr/lib”下進行查找,也就是鏈接到libc.so.6庫函數(shù)中去,這樣就能實現(xiàn)函數(shù)“printf”,而這也就是鏈接的作用。GCC編譯實際源程序編譯過程中,不需要分步運行上述命令來生成可執(zhí)行文件,可以利用下面命令一步到位,生成可執(zhí)行文件hello。[root@localhostgcc]#gcc–Shello.i–ohello.s運行生成的可執(zhí)行文件hello,得到運行結(jié)果:[root@localhostgcc]#./helloHello!Thisisourembeddedworld!常用的GCC編譯選項選項含義-E只進行預編譯,不做其他處理-c只編譯不鏈接,生成目標文件“.o”-S只編譯不匯編,生成匯編代碼-ofile指定輸出文件名稱為file-g在可執(zhí)行程序中包含標準調(diào)試信息-v打印出編譯器內(nèi)部編譯各過程的命令行信息和編譯器的版本-Idir在頭文件的搜索路徑列表中添加dir目錄-Ldir在庫文件的搜索路徑列表中添加dir目錄-static鏈接靜態(tài)庫-llibrary鏈接名為library的庫文件告警和出錯輔助選項選項含義-ansi支持符合ANSI標準的C程序-pedantic允許發(fā)出ANSIC標準所列的全部警告信息-pedantic-error允許發(fā)出ANSIC標準所列的全部錯誤信息-w關(guān)閉所有告警-Wall允許發(fā)出GCC提供的所有有用的報警信息-werror把所有的告警信息轉(zhuǎn)化為錯誤信息,并在告警發(fā)生時終止編譯過程/03Gdb調(diào)試器Gdb調(diào)試Linux下C程序開發(fā)主要用到的調(diào)試工具是Gdb調(diào)試器。Gdb是一款由GNU開發(fā)并發(fā)布的自由軟件,是UNIX/Linux下的功能強大的程序調(diào)試工具。雖然,它沒有圖形化的友好界面,但是它強大的功能也足以與微軟的VC工具等媲美。一般來說,Gdb主要提供以下功能:(1)設(shè)置斷點(可以是條件表達式),使程序在指定的代碼上暫停執(zhí)行。(2)單步執(zhí)行程序,便于調(diào)試。(3)查看程序中變量值的變化。(4)動態(tài)改變程序執(zhí)行環(huán)境。(5)分析崩潰產(chǎn)生的core文件。Gdb的調(diào)用Gdb的使用非常簡單,只要在Linux的命令提示符下輸入gdb,系統(tǒng)便會啟動Gdb,并打印出Gdb的相關(guān)信息。也可以在gdb后面給出文件名,直接指定想要測試的程序,Gdb就會自動調(diào)用這個可執(zhí)行文件進行調(diào)試,命令格式如下:注:為了使Gdb正常工作,程序在編譯的時候必須包含調(diào)試信息,這需要在GCC編譯時加上-g或者-ggdb選項。[root@localhostGdb]#gdbGNUgdb(Ubuntu7.11.1-0ubuntu1~16.5)7.11.1Copyright(C)2016FreeSoftwareFoundation,Inc.LicenseGPLv3+:GNUGPLversion3orlater<http:gnu="gnu">Thisisfreesoftware:youarefreetochangeandredistributeit.ThereisNOWARRANTY,totheextentpermittedbylaw.Type"showcopying"and"showwarranty"fordetails.ThisGDBwasconfiguredas"x86_64-linux-gnu".Type"showconfiguration"forconfigurationdetails.Forbugreportinginstructions,pleasesee:<http:///software/gdb/bugs/>.FindtheGDB

溫馨提示

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

評論

0/150

提交評論