日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

LV.2 Linux C语言高级

發布時間:2023/12/20 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LV.2 Linux C语言高级 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

D1 軟件包管理及shell命令

環境安裝

裝虛擬機需要將宿主機的虛擬化功能打開。
重啟電腦。

Linux介紹

1969年,由KenThompson在AT&T貝爾實驗室實現的。使用的是用匯編語言。
1970年,KenThompson(肯·湯普遜)和DennisRitchie(丹尼斯·里奇)使用 C語言對整個系統進行了再加工和編寫,使得Unix能夠很容易的移植到其他硬件的計算機上。

Unix家庭樹

什么是Linux?

GNU&GPL 參考1 參考2

Linux確實存在,許多人都在使用它,但它僅僅是所用系統的一部分。Linux是內核:它是為你運行的其他程序分配計算機資源的程序。內核是操作系統的基本部分,但是它自己并無用處;它只能在完整的操作系統框架下才能發揮作用。Linux一般和GNU操作系統一起使用:整個系統基本上就是GNU加上Linux,或叫GNU/Linux。所有被叫做“Linux”的發行版實際上是GNU/Linux發行版。

GNU = GNU is Not Unix
由Richard Stallman(理查德·斯托曼)在1984創建
最初的軟件:gcc、make、glibc…
GPL = General Public License (自由軟件保護條款)

What is Copyleft? - GNU Project - Free Software Foundation(自由軟件基金會)
學習用Ubuntu(每年4月份10月份發行一次)下載Ubuntu桌面系統 | Ubuntu
Linux發行版本


脫穎而出的Ubuntu

Ubuntu發行版本代號

體系結構

  • 內核更新非常快,三天兩頭更新 The Linux Kernel Archives
  • 選擇命令終端窗口
    目前,在桌面環境下的命令終端仿真器程序有很多,它們各有特色,都擁有各自的用戶群。目前流行的終端窗口有:
    Xterm、
    Gnome-terminal、
    Konsole、
    Rxvt等
    Ubuntu Linux默認安裝的命令終端有Gnome-terminal、Xterm,其他的命令終端都需要另行安裝。
  • Gnome-terminal是GNOME默認的命令終端。比Xterm具有更多、更強的功能,提供了剪切、粘貼、多標簽顯示,以及設置終端配置文件等功能,中文支持和用戶界面也很友好。用戶可以使用窗口菜單,或快捷鍵完成操作。

    deb軟件包管理機制

    流行的兩種軟件包管理機制

    Debian Linux(一種自由操作系統)首先提出軟件包”的管理機制,Deb軟件包;Redhat Linux(紅帽)由此提出了 Rpm 軟件包
    將應用程序的二進制文件、配置文檔、man/info幫助頁面等文件合并打包在一個文件中,用戶使用軟件包管理器直接操作軟件包,完成獲取、安裝、卸載、查詢等操作。隨著Linux操作系統規模的不斷擴大,系統中軟件包間復雜的依賴關系,導致Linux用戶麻煩不斷。
    隨著Linux操作系統規模的不斷擴大,系統中軟件包間復雜的依賴關系,導致Linux用戶麻煩不斷。
    Debian Linux開發出了APT(Advanced Packaging Tool)軟件包管理器。
    檢查和修復軟件包依賴關系
    利用Internet網絡幫助用戶主動獲取軟件包
    APT工具再次促進了Deb軟件包更為廣泛地使用,成為Debian Linux的一個無法替代的亮點。

    軟件包的類型

    Ubuntu有兩種類型的軟件包:二進制軟件包(deb)和源碼包(deb-src)
    二進制軟件包(Binary Packages):它包含可執行文件、庫文件、配置文件、man/info頁面、版權聲明和其它文檔。
    源碼包(Source Packages):包含軟件源代碼、版本修改說明、構建指令以及編譯工具等。先由tar工具歸檔為.tar.gz文件,然后再打包成.dsc文件。
    在用戶不確定一個軟件包類型時,可以使用file命令查看文件類型。

    軟件包的命名

    dpkg(Debian Package”的簡寫)命令

    軟件包管理工具分類

    根據用戶交互方式的不同,可以將常見的軟件包管理工具分為三類。

    命令行軟件包管理工具(dpkg):
    dpkg -i 安裝一個在本地文件系統上存在的Debian軟件包
    dpkg -r 移除一個已經安裝的軟件包
    dpkg -P 移除已安裝軟件包及配置文件
    dpkg -L 列出安裝的軟件包清單
    dpkg -s 顯出軟件包的安裝狀態
    文本窗口軟件包管理工具:

    aptitude為一個高級包管理工具,也是目前首選的字符界面 APT前端。
    一旦開始使用,最好一直使用它。否則將失去其包存放的軟件安裝清單,就不能享受自動刪除多余軟件包的功能

    aptitude工具也可以在命令行操作
    aptitude update 更新可用的包列表
    aptitude upgrade 升級可用的包
    aptitude dist-upgrade 將系統升級到新的發行版
    aptitude install pkgname 安裝包
    aptitude remove pkgname 刪除包
    aptitude purge pkgname 刪除包及其配置文件
    aptitude search string 搜索包
    aptitude show pkgname 顯示包的詳細信息
    aptitude clean 刪除下載的包文件
    aptitude autoclean 僅刪除過期的包文件

    圖形界面軟件包管理工具(synaptic ):

    APT 工作原理

    Ubuntu采用集中式的軟件倉庫機制,將各式各樣的軟件包分門別類地存放在軟件倉庫中,進行有效地組織和管理。然后,將軟件倉庫置于許許多多的鏡像服務器中,并保持基本一致。因此,對于用戶,這些鏡像服務器就是他們的軟件源(reposity)。

    在Ubuntu系統中,使用軟件源配置文件/etc/apt/sources.list 列出最合適訪問的鏡像站點地址。 軟件源配置文件只是告知Ubuntu系統可以訪問的鏡像站點地址。但那些鏡像站點都擁有什么軟件資源并不清楚。若是每安裝一個軟件包,就在服務器上尋找一邊,效率是很低的。因而,就有必要為這些軟件資源列個清單(建立索引文件),以便本地主機查詢。這就是APT軟件包管理器的工作原理。

    軟件源配置文件

    /etc/apt/sources.list。本質就是一個普通的文本文件,可以在超級管理員授權下,使用任何文本編輯器進行編輯。在該文件中,添加的軟件源鏡像站點稱為一個配置項,并遵循以下格式:

    軟件源

    根據軟件包的開發組織對該軟件的支持程度,以及遵從的開源程度,劃分為如下四類:
    核心(Main):官方維護的開源軟件,是由Ubuntu官方完全支持的軟件,包括大多數流行的、穩定的開源軟件,是Ubuntu默認安裝的基本軟件包;
    公共(Universe):社區維護的開源軟件,是由Ubuntu社區的計算機愛好者維護的軟件。這些軟件包沒有安全升級的保障。用戶在使用時,需要考慮這些軟件包存在的不穩定性;
    受限(Restricted):官方維護的非開源軟件,是專供特殊用途,而且沒有自由軟件版權,不能直接修改軟件,但依然被Ubuntu團隊支持的軟件;
    多元化(Multiverse):非Ubuntu官方維護的非開源軟件,用戶使用這些軟件包時,需要特別注意版權問題。

    刷新軟件源

    修改了配置文件——/etc/apt/sources.list,目的只是告知軟件源鏡像站點的地址。但那些所指向的鏡像站點所具有的軟件資源并不清楚,需要將這些資源列個清單,以便本地主機知曉可以申請哪些資源。
    使用“apt-get update”命令會掃描每一個軟件源服務器,并為該服務器所具有軟件包資源建立索引文件,存放在本地的/var/lib/apt/lists/目錄中。

    dpkg和apt軟件包管理器有什么區別?

    dpkg 在命令行模式下完成軟件包管理任務。為完成軟件包的獲取、查詢、軟件包依賴性檢查、安裝、卸載等任務,需要使用各自不同的命令Debian Linux開發出了APT軟件包管理器。 用于,檢查和修復軟件包依賴關系 ,利用Internet網絡幫助用戶主動獲取軟件包

    管理軟件包

    在Ubuntu Linux中,通常使用apt-get命令管理軟件包,只需告知軟件包名字,就可以自動完成軟件包的獲取、安裝、編譯和卸載,以及檢查軟件包依賴關系。 apt-get命令提供了一個軟件包管理的命令行平臺。在這個平臺上使用更豐富的子命令,完成具體的管理任務。apt-get subcommands(子命令) [ -d | -f | -m | -q | --purge | --reinstall | - b | - s | - y | - u | - h | -v ] (選項) pkg


    修復軟件包依賴關系

    如果由于故障而中斷軟件安裝過程,可能會造成關聯的軟件包只有部分安裝。之后,用戶就會發現該軟件既不能重裝又不能刪除。
    作為組合命令,下面前者用于檢查軟件包依賴關系,后者用于修復依賴關系。
    “apt-get check”——“apt-get -f install”
    在處理依賴關系上,apt-get會自動下載并安裝具有依賴關系(depends)的軟件包,但不會處理與安裝軟件包存在推薦(recommends)和建議(suggests)關系的軟件包。

    更新軟件包

    在Ubuntu Linux中,只需使用命令“apt-get upgrade”就可以輕松地將系統中的所有軟件包一次性升級到最新版本

    安裝軟件包

    在準備好軟件源并連通網絡后,用戶只需告知安裝軟件的名稱,“apt-get install”命令就可以輕松完成整個安裝過程,而無須考慮軟件包的版本、優先級、依賴關系等。使用“apt-get install”下載軟件包大體分為四步:STEP1,掃描本地存放的軟件包更新列表(由apt-get update命令刷新更新列表),找到最新版本的軟件包;STEP2,進行軟件包依賴關系檢查,找到支持該軟件正常運行的所有軟件包;STEP3,從軟件源所指的鏡像站點中,下載相關軟件包;STEP4 ,解壓軟件包,并自動完成應用程序的安裝和配置。

    重新安裝軟件包

    當用戶不小心損壞了已安裝的軟件包,而需要修復。或者,希望重新安裝軟件包中某些文件的最新版本,可以重新安裝軟件包。

    卸載軟件包

    不完全卸載 “apt-get remove”會關注那些與被刪除的軟件包相關的其它軟件包,刪除一個軟件包時,將會連帶刪除與該軟件包有依賴關系的軟件包。完全卸載 “apt-get --purge remove”命令在卸載軟件包文件的同時,還刪除該軟件包所使用的配置文件。

    清理軟件包緩沖區

    清理軟件包緩沖區.如果用戶認為軟件包緩沖區中的文件沒有任何價值了,有必要刪除全部下載的軟件包。可以使用“apt-get clean”清理整個軟件包緩沖區,除了lock鎖文件和partial目錄。


    按照依賴關系清理緩沖區中多余的軟件包 如果用戶希望緩沖區中只保留最新版本的軟件包,多余版本全部清除,可以使用“apt-get autoclean”命令。

    查詢軟件包描述信息


    使用“apt-cache show”命令獲取指定軟件包的詳細信息,包括軟件包安裝狀態、優先級、適用架構、版本、存在依賴關系的軟件包,以及功能描述。該命令可以同時顯現多個軟件包的詳細信息。

    獲取軟件包安裝狀態

    使用“apt-cache policy”可以獲取軟件包當前的安裝狀態如果用戶僅想了解某個軟件包依賴于哪些軟件包,可以使用“apt-cache depends”命令如果用戶僅想了解某個軟件包被哪些軟件包所依賴,可以使用“apt-cache rdepends”命令。

    總結與思考

    本節課主要講解了APT軟件包管理器的工作原理及主要命令。
    下列文件什么作用?
    /etc/apt/sources.list
    /var/lib/apt/lists/*
    /var/cache/apt/archives

    shell基本命令

    shell簡介

    shll 直譯為貝殼 ,Linux內核的一個外層保護工具,完成用戶與內核之間的交互。將用戶的命令或按鍵轉化程序內核所能夠理解的指令,控制操作系統做出響應,直到控制相關硬件設備。然后,將輸出結果通過shell提交給用戶。
    命令是用戶向系統內核發出控制請求,與之交互的文本流。
    shell是一個命令行解釋器,將用戶命令解析為操作系統所能理解的指令,實現用戶與操作系統的交互。
    當需要重復執行若干命令,可以將這些命令集合起來,加入一定的控制語句,編輯成為shell腳本文件,交給shell批量執行。
    用戶在命令行提示符下鍵入命令文本,開始與Shell進行交互
    接著,shell將用戶的命令或按鍵轉化成內核所能夠理解的指令
    控制操作系統做出響應,直到控制相關硬件設備
    然后,shell將輸出結果通過shell提交給用戶

    選擇shell

    最初的UNIX shell經過多年的發展,由不同的機構、針對不同的目的,開發出許多不同類型的shell程序。目前流行的shell主要有幾種 :

    • Bourne(/b??n/ 小溪) Shell(簡稱sh):它是Unix的第一個shell程序,早已成為工業標準。目前幾乎所有的Linux系統都支持它。不過Bourne Shell的作業控制功能薄弱,且不支持別名與歷史記錄等功能。
    • C Shell(簡稱csh)
    • Korn Shell(簡稱ksh)
    • Bourne Again Shell(簡稱bash):能夠提供環境變量以配置用戶Shell環境,支持歷史記錄,內置算術功能,支持通配符表達式,將常用命令內置簡化。

    體驗shell命令的樂趣

    立即關機與重啟
    使用系統中的圖形界面

    使用shell命令

    在命令行鍵入以上命令,系統立即關機 :


    在命令行鍵入以上命令,系統立即重新啟動 :
    定時關機sudo shutdown -h +45 “this is all,game over.” 時間限定在45分鐘內,否則計算機將自動關機
    定時重啟sudo shutdown -r +60 計算機會在60分鐘后自動重啟

    shell命令格式

    shell提示符標識了命令行的開始。用戶在提示符后面輸入一條命令并按Enter鍵,完成向系統提交指令。
    通常shell命令提示符采用以下的格式:

    username:用戶名,顯示當前登錄用戶的賬戶
    hostname:主機名,顯示登錄的主機名,例如若遠 程登錄后,則顯示登錄的主機名;
    direction:目錄名,顯示當前所處的路徑,當在根目錄下顯示為“/”,當在用戶主目錄下顯示為“~”;

    通常一條命令包含三個要素:命令名稱、選項、參數。命令名稱是必須的,選項和參數都可能是可選項。命令格式如下所示:

    KaTeX parse error: Expected 'EOF', got '#' at position 28: …當前用戶為超級用戶,提示符為“#?”,其他用戶的提示符均為“”;
    Command:命令名稱,Shell命令或程序,嚴格區分大小寫
    Options:命令選項,用于改變命令執行動作的類型,由“-”引導,可以同時帶有多個選項;
    Argument:命令參數,指出命令作用的對象或目標,有的命令允許帶多個參數。

    通常一條命令包含三個要素:命令名稱、選項、參數。命令名稱是必須的,選項和參數都可能是可選項。命令格式如下所示:

    KaTeX parse error: Expected 'EOF', got '#' at position 28: …當前用戶為超級用戶,提示符為“#?”,其他用戶的提示符均為“”;
    Command:命令名稱,Shell命令或程序,嚴格區分大小寫
    Options:命令選項,用于改變命令執行動作的類型,由“-”引導,可以同時帶有多個選項;
    Argument:命令參數,指出命令作用的對象或目標,有的命令允許帶多個參數。

    一條命令的三要素中間用空格隔開
    多行命令用 ‘;’ 分隔。
    同一行命令換行結尾加 ‘\’ 聲明未結束。

    不帶選項和參數

    ls命令未帶任何參數,列出當前目錄中的所有文件,只顯示文件名稱。
    命令不帶選項或參數,通常意為使用默認選項或參數。

    命令行操作

    bash(Bourne Again Shell,簡稱bash)除了在命令編輯功能上比sh有很大改進外,還增加了特有功能極大地方便了用戶在Shell命令行上的操作。
    補齊命令與文件名 :按兩下TAB或ESC鍵,用戶命令補全, 按一次TAB用于文件名補全。
    查詢命令歷史 : history

    總結與思考

    本節課先對shell做了基本介紹,然后講解了linux命令的基本格式,最后介紹了常見的命令行操作
    思考:
    什么是shell?
    如何更改歷史記錄容量?
    歷史記錄如何刪除?

    shell中的特殊字符

    通配符

    當需要用命令處理一組文件,例如file1.txt、file2.txt、file3.txt……,用戶不必一一輸入文件名,可以使用shell通配符。shell命令的通配符含義如下表

    管道

    管道可以把一系列命令連接起來,意味著第一個命令的輸出將作為第二個命令的輸入,通過管道傳遞給第二個命令,第二個命令的輸出又將作為第三個命令的輸入,以此類推。就像通過使用“|”符連成了一個管道。

    以上操作中,借助管道“|”,將ls的輸出直接作為wc命令的輸入。使用管道可以巧妙的將一些命令聯合使用,得到單個命令所無法實現的效果。例如使用以上的命令組合,得到的是/usr/bin目錄下文件的個數。

    grep -rn “Linux” /etc/passwd | wc -w 查看文件行數

    總結與思考

    本節課主要介紹了shell中的幾種特殊字符的用法以及管道的使用
    思考
    shell中有哪些特殊字符?
    shell中管道的作用?
    shell中grep命令和管道如何結合?

    輸入/輸出重定向

    輸入/輸出重定向是改變shell命令或程序默認的標準輸入/輸出目標,重新定向到新的目標。
    linux中默認的標準輸入定義為鍵盤,標準輸出定義為終端窗口。
    用戶可以為當前操作改變輸入或輸出,迫使某個特定命令的輸入或輸出來源為外部文件。

    cat命令功能為在標準輸出上顯示文件。下面通過一個實例,可以更好地理解重定向的功能。

    命令置換

    命令替換是將一個命令的輸出作為另一個命令的參數。命令格式如下所示。
    其中,命令command2的輸出將作為命令command1的參數。需要注意,命令置換的單引號為ESC鍵下方的“`”鍵
    pwd命令用于顯示當前目錄的絕對路徑。在上面的命令行中,使用命令置換符,將pwd的運行結果作為ls命令的參數。最終,命令執行結果是顯示當前目錄的文件內容。

    總結與思考

    本節課首先介紹了shell中的輸入輸出重定向的用法,然后介紹了命令置換的 使用
    思考:
    什么叫輸入輸出重定向?
    有哪些輸入輸出重定向符?

    D2 linux shell命令

    2.1shell基本系統維護命令

    獲取聯機幫助

    man 可以找到特定的聯機幫助頁,man ls 。聯機幫助頁提供了指定命令commandname的相關信息,包括:名稱、函數、語法以及可選參數描述等。無論幫助有多長,都遵循這個格式顯示。在頁面很多的情況下使用PageUp和PageDown鍵翻頁。最后,使用“:q”退出幫助頁面。

    NAME:命令的名稱 SYNOPSIS:命令的語法格式 DESCRIPTION:命令的一般描述以及用途 OPTIONS:描述命令所有的參數或選項 SEE ALSO:列出聯機幫助頁中與該命令直接相關或功能相近的其他命令 BUGS:解釋命令或其輸出中存在的任何已知的問題或缺陷 EXAMPLES:普通的用法示例 AUTHORS:聯機幫助頁以及命令的作者

    基本系統維護命令

    passwd 修改當前用戶的口令,sudo passwd

    出于系統安全考慮,Linux系統中的每一個帳號都必須同時具備用戶名和密碼。 可以使用passwd命令,為已有賬戶重新修改用戶口令。 需要說明的是,超級用戶root可以修改所有其他用戶的口令,而普通用戶只能修改自己的用戶口令,如果確要修改超級用戶或其他用戶口令的話,需要具有超級用戶的權限 passwd命令的一般語法格式為:


    單獨使用passwd命令,意為修改當前用戶自己的口令。下面命令實例用于修改用戶自己的口令。

    su
    單獨使用su命令,默認為要轉換為超級用戶root。
    su命令用于臨時改變用戶身份,具有其他用戶的權限。普通用戶可以使用su命令臨時具有超級用戶的權限;超級用戶也可以使用普通用戶身份完成一些操作。當需要放棄當前用戶身份,可以使用exit命令切換回來。su命令的一般語法格式為:

    選項“-c”表示執行一個命令后就結束;-m表示仍保留環境變量不變;-表示轉換用戶身份時,同時使用該用戶的環境。

    echo
    echo命令用于在標準輸出——顯示器上顯示一段文字,一般起到提示作用。echo命令的一般語法格式為:

    選項-n表示輸出文字后不換行。提示信息字符串可以加引號,也可以不加。

    date

    date命令用于顯示和設置系統日期和時間。date命令的一般語法格式為:

    選項-s表示按照datestr日期顯示格式設置日期;單獨使用date命令,用于顯示系統時鐘中當前日期。時間的格式為:“hh:mm:ss”,日期格式為:“mm/dd/yy”。

    clear 清屏 ctrl + l

    df
    df命令用于查看磁盤空間的使用情況。查看磁盤空間是用戶應當經常做的事情,因為誰也不希望看到根或/var分區在不經意間填滿,以便及時清理。df命令的一般格式為:

    其中,參數Filesystem表示物理文件系統。各選項的含義如表所示。

    從以下命令的執行結果可以看到,這臺計算機只有一塊硬盤(/dev/sda1),文件格式類型為Ext3,已經使用36%的存儲空間。同時,可以發現計算機上還安裝了CD-ROM(/dev/hdc)、USB存儲器(/dev/sdb1)。其他分區均為專用的虛擬文件系統

    df 命令常用參數:
    -a :列出所有文件系統
    -k :列出磁盤的分配情況(KB)
    -h :同-k, 但大小以G、M,K單位顯示
    -l :僅列出本地文件系統
    例:
    #df -h

    du
    列出目錄和文件使用的磁盤塊。出目錄和文件所使用的磁盤塊數,每塊占512個字節。
    ???????常用參數:
    -a :僅列出空閑的文件數
    -h :列出磁盤的使用情況(KB)
    -s :列出總的空閑空間(KB)
    例: #du –h /etc???????

    2.2用戶管理

    / etc :etc是Etcetera的縮寫,是“等等”的意思,用于存放所有系統管理所需要的配置文件和子目錄,基本上硬件和軟件配置文件都在此目

    用戶管理

    用戶的屬性
    用戶名
    口令
    用戶ID(UID)
    用戶主目錄(HOME)
    用戶shell

    /etc/passwd文件

    /etc/passwd文件是系統能夠識別的用戶清單。用戶登陸時,系統查詢這個文件,確定用戶的UID并驗證用戶口令
    登陸名
    經過加密的口令
    UID
    默認的GID
    個人信息
    主目錄
    登陸shell

    /etc/group文件

    包含了UNIX組的名稱和每個組中成員列表,每一行代表一個組,包括四個字段,組名、加密的口令、GID號、成員列表,彼此用逗號隔開。

    group文件實例

    添加用戶

    adduser
    語法:adduser
    實例:
    # adduser newuser
    添加用戶名為newuser的新用戶

    adduser配置文件

    /etc/adduser.conf
    FIRST_UID=1000
    LAST_UID=29999
    USERS_GID=100
    DHOME=/home
    DSHELL=/bin/bash
    SKEL=/etc/skel

    SKEL模板

    /etc/skel目錄是被 /usr/sbin/useradd使用
    把想要新用戶擁有的配置文件從/etc/skel目錄拷貝,常用的文件:
    .bash_profile
    .bashrc
    .bash_logout
    .dircolors
    .inputrc
    .vimrc

    添加新用戶的過程

    系統
    編輯passwd和shadow文件,定義用戶帳號
    設置一個初始口令
    創建用戶主目錄,用chown和chmod命令改變主目錄 的屬主和屬性
    為用戶所進行的步驟
    將默認的啟動文件復制到用戶主目錄中
    設置用戶的郵件主目錄并建立郵件別名

    2.2用戶管理相關命令介紹

    設置初始口令

    使用passwd命令可以修改用戶口令
    root用戶可以修改任何用戶的口令
    語法:passwd [-k] [-l] [u] [-f] [-d] [-S] username
    使用方法:
    passwd username

    修改用戶屬性

    usermod
    語法:usermod [-u uid [-o]] [-g group] [-G gropup,…]
    [-d home [-m]] [-s shell] [-c comment]
    [-l new_name] [-f inactive][-e expire]
    [-p passwd] [-L|-U] name

    舉例用戶oldname改名為newname,注意要同時更改家目錄:
    usermod –d /home/newname –m –l newname oldname

    刪除用戶

    deluser
    語法: deluser
    使用方法:
    deluser --remove-home user1
    刪除用戶user1的同時刪除用戶的工作目錄

    添加用戶組

    addgroup
    語法: addgroup groupname
    使用方法:
    addgroup groupname

    刪除用戶組

    delgroup
    語法: delgroup groupname
    使用方法:
    delgroup groupname1

    總結與思考

    本節課主要介紹了linux系統中用戶管理相關的重要配置文件以及用戶管理相關的命令。
    思考
    用戶相關的文件有哪些?
    簡述添加用戶的過程。

    2.3進程管理的相關命令

    進程的概念

    程序的一次執行就是一個進程

    使用命令查看進程

    ps 命令

    顯示進程 (process) 的動態
    語法:
    ps [options]

    ps命令基本選項及參數釋義

    a:顯示現行終端機下的所有程序,包括其他用戶的程序。
    c:列出程序時,顯示每個程序真正的指令名稱,而不包含路徑,選項或常駐服務的標示。
    e:列出程序時,顯示每個程序所使用的環境變量。
    f:用ASCII字符顯示樹狀結構,表達程序間的相互關系。
    g:顯示現行終端機下的所有程序,包括群組領導者的程序。
    h:不顯示標題列。
    u:以用戶為主的格式來顯示程序狀況。
    x:顯示所有程序,不以終端機來區分。
    r:只列出現行終端機正在執行中的程序。
    v:采用虛擬內存的格式顯示程序狀況
    -a:顯示所有終端機下執行的程序,除了階段作業領導者之外。
    -c:顯示CLS和PRI欄位。
    -d:顯示所有程序,但不包括階段作業領導者的程序。
    -e:顯示所有程序。
    -f:顯示UID,PPIP,C與STIME欄位。
    -H:顯示樹狀結構,表示程序間的相互關系。
    -u<用戶識別碼>:列出屬于該用戶的程序的狀況,也可使用用戶名稱來指定。
    -j:采用工作控制的格式顯示程序狀況
    -l或l:采用詳細的格式來顯示程序狀況。

    常見的用法:
    ps -elf 普通使用的標準
    ps -aux BSD 使用的標準

    進程的狀態標志

    D: 不可中斷的靜止
    R: 正在執行中
    S: 阻塞狀態
    T: 暫停執行
    Z: 不存在但暫時無法消除
    <: 高優先級的進程
    N: 低優先級的進程
    L: 有內存分頁分配并鎖在內存中

    top命令

    監視進程
    通常會全屏顯示,而且會隨著進程狀態的變化不斷更新
    整個系統的信息也會顯示,為查找問題提供了便利
    可以顯示系統總共有多少CPU和內存資源以及負載平衡等信息。
    top 實時檢測進程 q退出

    pstree命令

    將所有行程以樹狀圖顯示, 樹狀圖將會以 pid (如果有指定) 或是以init這個基本進程為根,如果有指定使用者id, 則樹狀圖會只顯示該使用者所擁有的進程。
    參數:
    -a 顯示該進程的完整指令及參數, 如果是被記憶體置換出去的進程則會加上括號
    -c 如果有重覆的進程名, 則分開列出

    cd /proc/ 常用查看進程信息命令

    終止進程

    使用kill命令終止進程
    kill [-signal] PID
    signal是信號,PID是進程號
    kill 命令向指定的進程發出一個信號signal,在默認情況下,kill 命令向指定進程發出信號15,正常情下,將殺死那些不捕捉或不忽略這個信號的進程
    kill -l 查看信號含義

    2.4文件系統的類型和結構

    文件系統的類型

    Linux文件系統

    在任何一個操作系統中,文件系統無疑是其最重要的組件,用于組織和管理計算機存儲設備上的大量文件,并提供用戶交互接口。Linux同樣具備完善的文件系統。用戶既可以使用界面友好的Nautilus圖形文件管理器,也可以使用功能強大的shell文件系統管理工具。

    文件系統類型

    linux是一種兼容性很高的操作系統,支持的文件系統格式很多,大體可分以下幾類:
    磁盤文件系統:指本地主機中實際可以訪問到的文件系統,包括硬盤、CD-ROM、DVD、USB存儲器、磁盤陣列等。常見文件系統格式有:autofs、coda、Ext(Extended File sytem,擴展文件系統)、Ext3、Ext4、VFAT、ISO9660(通常是CD-ROM)、UFS(Unix File System,Unix文件系統)、FAT、FAT16、FAT32、NTFS等;
    網絡文件系統:是可以遠程訪問的文件系統,這種文件系統在服務器端仍是本地的磁盤文件系統,客戶機通過網絡遠程訪問數據。常見文件系統格式有:NFS、Samba等;
    專有/虛擬文件系統:不駐留在磁盤上的文件系統。常見格式有:TMPFS(臨時文件系統)、PROCFS(Process File System,進程文件系統)和LOOPBACKFS(Loopback File System,回送文件系統)。

    目前Ext4是Linux系統廣泛使用的一種文件格式。在Ext3基礎上,對有效性保護、數據完整性、數據訪問速度、向下兼容性等方面做了改進。
    最大特點是日志文件系統:可將整個磁盤的寫入動作完整地記錄在磁盤的某個區域上,以便在必要時回溯追蹤。

    查看文件系統的命令

    mount\df\file\parted


    SCSI與IDE設備命名

    sata硬盤的設備名稱是“/dev/sda”
    /dev/sda1 含義?
    /dev/sdb3 含義?
    IDE硬盤的設備名稱是“/dev/hda”
    /dev/hdc2 含義?
    如果很在意系統的高性能和穩定性,應該使用SCSI硬盤
    cat /proc/partitions

    Linux分區的命名方式

    字母和數字相結合
    前兩個字母表示設備類型
    “hd”代表IDE硬盤
    “sd”表示SCSI或SATA硬盤
    第三個字母說明具體的設備
    “/dev/hda”表示第一個IDE硬盤
    “/dev/hdb”表示第二個IDE硬盤

    交換分區

    將內存中的內容寫入硬盤或從硬盤中讀出,稱為內存交換(swapping)
    交換分區最小必須等于計算機的內存
    可以創建多于一個的交換分區
    盡量把交換分區放在硬盤驅動器的起始位置

    Linux文件系統的結構

    文件系統邏輯結構

    某所大學的學生可能在一兩萬人左右,通常將學生分配在以學院-系-班為單位的分層組織機構中。若需要查找一名學生時,最笨的辦法是依次問詢大學中的每一個學生,直到找到為止。如果按照從學院、到系、再到班的層次查詢下去,必然可以找到該學生,且查詢效率高。這種樹形的分層結構就提供了一種自頂向下的查詢方法。
    如果把學生看作文件,院-系-班的組織結構看作是Linux文件目錄結構,那么就同樣可以有效地管理數量龐大的文件。
    一直使用微軟Windows操作系統的用戶似乎已經習慣了將硬盤上的幾個分區,并用A:、B:、C:、D:等符號標識。存取文件時一定要清楚存放在哪個磁盤的哪個目錄下。
    Linux的文件組織模式猶如一顆倒置的樹,這與Windows文件系統有很大差別。所有存儲設備作為這顆樹的一個子目錄。存取文件時只需確定目錄就可以了,無需考慮物理存儲位置。

    分區與目錄的關系

    在Windows下,目錄結構屬于分區;在Linux下,分區屬于目錄結構。
    如何知道文件存儲的具體硬件位置呢?
    在Linux中,將所有硬件都視為文件來處理,包括硬盤分區、CD-ROM、軟驅以及其他USB移動設備等。為了能夠按照統一的方式和方法訪問文件資源,Linux中提供了對每種硬件設備相應的設備文件。一旦Linux系統可以訪問到硬件,就將其上的文件系統掛載到目錄樹中的一個子目錄中。
    例如,用戶插入USB移動存儲器,Ubuntu Linux自動識別后,將其掛載到“/media/disk”目錄下。而不象Windows系統將USB存儲器作為新驅動器,表示為“F:”盤。

    Linux文件系統就是一個樹形的分層組織結構。將根(/)作為整個文件系統的惟一起點,其他所有目錄都從該點出發。將Linux的全部文件按照一定的用途歸類,合理地掛載到這顆“大樹”的“樹枝”或“樹葉”上,如圖所示。而這些全不用考慮文件的實際存儲位置,無論是存在硬盤上,還是在CD-ROM或USB存儲器中,甚至是網絡終端。

    基本目錄

    由于Linux是完全開源的軟件,各Linux發行機構都可以按照自己的需求對文件系統進行裁剪,所以如此眾多的Linux發行版本的目錄結構也不盡相同。為了規范文件目錄命名和存放標準,頒發了文件層次結構標準(FHS,File Hierarchy Standard),2004年發行版本FHS 2.3。Ubuntu Linux系統同樣也遵循這個標準


    絕對路徑和相對路徑
    在認識到Linux文件系統是樹形分層的組織結構,且只有一個根節點之后。在Linux文件系統中查找一個文件,只要確定文件名和路徑,就可以惟一確定這個文件。例如
    “/usr/games/gnect”
    絕對路徑:指文件在文件系統中的準確位置。通常在本地主機上,以根目錄為起點。例如“/usr/games/gnect”就是絕對路徑。
    相對路徑:指相對于用戶當前位置的一個文件或目錄的位置。例如,用戶處在usr目錄中時,只需要“games/gnect”就可確定這個文件。

    Linux文件系統與Windows文件系統比較

    2.5文件系統相關命令

    file、ln命令

    file命令

    在Linux文件系統中,文件擴展名不總是被使用或被一致地使用。如果一個文件沒有擴展名,或者文件與其擴展名不符時怎么辦呢?file命令功能用于判定一個文件的類型。file命令一般語法格式為:
    file [ filename ]
    其中filename是文件名。命令的輸出將顯示該文件是二進制文件、文本文件、目錄文件、設備文件,還是Linux中其他類型的文件。

    創建鏈接文件

    鏈接文件:在文件之間創建鏈接。這種操作實際上是給系統中已有的某個文件指定另外一個可用于訪問它的名稱。
    Linux中有兩種類型的鏈接:
    硬鏈接是利用Linux中為每個文件分配的物理編號——inode建立鏈接。因此,硬鏈接不能跨越文件系統。
    軟鏈接(符號鏈接)是利用文件的路徑名建立鏈接。通常建立軟鏈接使用絕對路徑而不是相對路徑,以最大限度增加可移植性。
    需要注意的是,如果是修改硬鏈接的目標文件名,鏈接依然有效;如果修改軟鏈接的目標文件名,則鏈接將斷開;對一個已存在的鏈接文件執行移動或刪除操作,有可能導致鏈接的斷開。假如刪除目標文件后,重新創建一個同名文件,軟鏈接將恢復,硬鏈接不再有效,因為文件的inode已經改變。

    ln命令

    命令可以用于創建文件的鏈接文件。ln命令一般語法格式為:
    ln [ -s ] target link_name
    其中,選項“-s”表示為創建軟鏈接。在缺省情況下,創建硬鏈接。參數target為目標文件,link_name為鏈接文件名。如果鏈接文件名已經存在但不是目錄,將不做鏈接。目標文件可以是任何一個文件名,也可以是一個目錄。

    以上命令為/proc/cpuinfo文件創建了一個軟鏈接文件。使用“ls –l”命令可以查看到新創建的鏈接文件所指向的目標文件名。

    文件的歸檔和壓縮

    壓縮文件

    用戶在進行數據備份時,需要把若干文件整合為一個文件以便保存。盡管整合為一個文件進行管理,但文件大小仍然沒變。若需要網絡傳輸文件時,就希望將其壓縮成較小的文件,以節省在網絡傳輸的時間。因此本節介紹文件的歸檔與壓縮。

    文件壓縮和歸檔

    歸檔文件是將一組文件或目錄保存在一個文件中。
    壓縮文件也是將一組文件或目錄保存一個文件中,并按照某種存儲格式保存在磁盤上,所占磁盤空間比其中所有文件總和要少。
    歸檔文件仍是沒有經過壓縮的,它所使用的磁盤空間仍等于其所有文件的總和。因而,用戶可以將歸檔文件再進行壓縮,使其容量更小。
    gzip是Linux中最流行的壓縮工具,具有很好的移植性,可在很多不同架構的系統中使用。bzip2在性能上優于gzip,提供了最大限度的壓縮比率。如果用戶需要經常在Linux和微軟Windows間交換文件,建議使用zip。

    目前,歸檔工具使用最廣泛的tar命令,可以把很多文件(甚至磁帶)合并到一個稱為tarfile的文件中,通常文件擴展名為.tar。然后,再使用zip、gzip或bzip2等壓縮工具進行壓縮。

    壓縮文件

    shell歸檔和壓縮工具
    使用shell歸檔和壓縮工具可以更直接地完成文檔的打包任務。由于該類shell命令是成對使用的,因此下面按對介紹相關命令。

    gzip與gunzip命令

    與zip明顯區別在于只能壓縮一個文件,無法將多個文件壓縮為一個文件。gzip命令符號模式的一般語法格式為:
    其中,filename表示要壓縮的文件名,gzip會自動在這個文件名后添加擴展名為.gz,作為壓縮文件的文件名。


    gunzip命令符號模式的一般語法格式為:

    其中,選項“-f”用于解壓文件時,對覆蓋同名文件不做提示。
    在執行gzip命令后,它將刪除舊的未壓縮的文件并只保留已壓縮的版本。以下命令以最大的壓縮率對文件file_1進行壓縮,生成file_1.gz文件。使用“-l”選項可以查看壓縮的相關信息。最后使用gunzip命令對文件進行了解壓。與壓縮時相反,file_1.gz文件會被刪除,繼之生成file_1。

    tar命令

    tar命令主要用于將若干文件或目錄合并為一個文件,以便備份和壓縮。當然,之后出現tar程序的改進版本,可以實現在合并歸檔的同時進行壓縮。tar命令符號模式的一般語法格式為:

    第一,將myExamples/目錄下的所有文件全部歸檔,打包到一個文件中myExamples.tar;
    第二,將myExamples/目錄下的所有文件全部歸檔,并使用bzip2壓縮成一個文件myExamples.tar.bz;
    第三,將myExamples/目錄下的所有文件全部歸檔,并使用gzip壓縮成一個文件myExamples.tar.gz。

    如果想查看一下歸檔文件中的詳細內容,使用類似以下命令:

    使用以下命令完成tar文件的釋放。其中,“tar -xjf”和“tar –xzf”等效與先解壓縮后釋放tar文件。

    Linux 網絡配置管理

    網絡配置基礎

    用戶既可以通過命令行的方式,也可以通過友好的圖形界面,輕松完成網絡配置。
    實現Linux網絡配置的惟一目標就是修改系統中眾多的網絡配置文件,如/etc/interfaces、/etc/hosts,/etc/resolv.conf 等等。

    通常,用戶可能使用普通以太網卡、無線網卡、調制解調器等不同類型的設備接入網絡。不同類型的網絡設備在主機中被映射為相應的網絡接口,比如以太網卡映射為eth,無線網卡映射為wlan。有時,用戶還可能同時使用多個網絡設備,就會出現eth0、eth1…,或wlan0、wlan1…的情況。
    那么,如何標識每個連接到Internet的網絡接口呢?
    解決辦法是:為每個網絡接口分配一個全世界范圍內惟一的32bit的標識符。這個標識符就是IP(Internet Protocol)地址。

    配置IP地址

    IP地址

    IP地址包括三部分:Internet網絡號(Net-ID)、子網號(Subnet-ID)和主機號(Host-ID)。

    因而可以這樣解釋:一個IP地址惟一標識了,處在某個互聯網中的,某個子網的,某個網絡接口。

    根據Internet網絡號的字段長度(1,2,3字節長),IP地址區分為A類、B類、C類。三類IP地址的掩碼如下所示。
    A類地址的默認子網掩碼是255.0.0.0,或0xFF000000;
    B類地址的默認子網掩碼是255.255.0.0,或0xFFFF0000;
    C類地址的默認子網掩碼是255.255.255.0,或0xFFFFFF00;
    IP網絡中通常用最小的IP地址標識網絡本身,將最大的IP地址作為該網絡的廣播地址,其余所有IP地址都分配給網絡中的主機。然而,局域網中的主機并不能直接訪問Internet,需要通過一個作為代理的網關或網絡地址轉換服務(NAT)才能訪問Internet。通常將IP地址的第一個或最后一個留給該網絡的Internet網關。

    配置IP地址

    接入網絡的計算機主機依靠IP地址,惟一地標識其在網絡中的身份,因此為主機配置IP地址是接入網絡的關鍵。配置IP地址的方法有兩種:
    配置靜態IP:在主機進入網絡之前,事先為主機設置固定 的IP地址;
    配置動態IP:選擇DHCP(動態主機配置協議(Dynamic host configuration protocol))網絡服務,在主機進入網絡之后,動態隨機獲取IP地址。

    網絡相關命令

    ifconfig命令

    ifconfig是GNU/Linux中配置網卡的基本命令,包含在net-tools軟件包中。它可用于顯示或設置網卡的配置,如IP地址、子網掩碼、最大分組傳輸數、IO端口等,還可以啟動或禁用網卡。ifconfig命令有以下兩種格式:

    ifconfig的第一種格式用于查看當前系統的網絡配置情況;第二種格式用于配置網卡,包括添加、刪除網卡,以及綁定多個IP地址等。

    從下面的運行結果可以看出,主機有兩個接口eth0、lo。lo代表主機本身,也稱回送接口(Loopback),其IP地址約定為127.0.0.1。

    如果主機安裝了第二塊、第三塊網卡,則有eth1,eth2標識。常見的接口類型還有以下幾種(N表示接口號):
    pppN表示調制解調設備
    wlanN表示無線網卡
    trN表示令牌環網卡
    如果只是關心某個網絡設備,可以在ifconfig后面加上接口名稱,則只顯示該設備的相關信息,例如:

    假設主機現有的IP地址為192.168.182.129,需要為其重新分配IP地址192.168.182.128,即。使用ipconfig命令設置主機的第一塊網卡(eth0)的IP地址。

    配置動態IP地址

    在大型網絡中,由于存在許多的移動計算機系統,隨時都可能進入網絡,在每次更換網絡時,就不得不重新配置網絡信息。如果計算機在網絡里能夠自動獲取IP地址、子網掩碼、路由表、DNS服務器地址等網絡信息,具有動態配置IP的能力,就可以大大簡化客戶端的網絡配置難度。動態主機配置協議(DHCP,Dynamic Host Configuration Protocol)可以實現動態分配IP資源。
    只要在局域網中架設有DHCP服務器,在Ubuntu Linux中為主機配置DHCP客戶端是非常容易的。需要說明的是,通常普通以太網卡和無線網卡可以配置動態IP,而調制解調器等網絡設備不能配置動態IP。

    動態IP的獲取過程

    可比作一個“租賃”過程。DHCP服務器好比是IP地址的出租方,用戶主機(即DHCP客戶端)好比是IP地址的臨時租用者。
    如果將用戶主機設置為DHCP客戶端之后,手動啟動網絡服務,就可以從執行結果中看出獲取動態IP的過程。

    執行過程中包括以下四個階段。
    客戶端尋找DHCP服務器(DHCPDISCOVER):客戶端廣播申請動態IP的請求;
    服務器提供可分配的IP地址(DHCPOFFER):所有接收到請求的DHCP服務器都將向客戶端提供一個IP地址;
    客戶端接受IP地址租借(DHCPREQUEST):客戶端從多個IP選擇中挑選一個,通知DHCP服務器,并標識出所選中的服務器;
    服務器確認租借IP(DHCPACK):被選中的DHCP服務器最后發出一個確認信息,包含IP地址、子網掩碼、默認網關、DNS服務器和租借期(客戶端使用這個IP的這段時間,稱為租借期)。
    最終客戶端臨時“租借”的IP地址為192.168.182.129。

    IP地址存放在哪里——interfaces配置文件

    無論是配置靜態IP還是動態IP,計算機系統將IP信息保存放在什么地方?答案是配置文件“/etc/network/interfaces”。在Ubuntu Linux啟動時就能獲得IP地址的配置信息。若是配置靜態IP,就從配置文件中讀取IP地址參數,直接配置網絡接口設備;若是配置動態IP,就通知主機通過DHCP協議獲取網絡配置。

    以下分別為配置靜態IP和動態IP時,配置文件“/etc/network/interfaces”的實例。

    DNS客戶端配置文件—resolv.conf

    Ubuntu Linux將DNS服務器地址保存在配置文件/etc/resolv.conf中。
    依然延續上面的例子,添加DNS服務器IP地址后,查看配置文件/etc/hosts,如下所示。

    ping命令

    ping(Packet Internet Groper)命令可能是最有名氣的網絡連接檢測工具。它使用了Internet控制報文協議(ICMP)回送請求與回送應答報文,測試兩個主機之間的連通性。該命令的一般格式如下所示。
    ping命令測試的遠程主機,既可用域名,也可用IP地址標識。

    可以使用該命令來判斷主機與遠程主機是否可達,或之間的網絡是否擁塞。min/avg/max/mdev是ping命令的完成測試后的統計結果,分別表示最小響應時間/平均響應時間/最大響應時間/響應時間方差。這些指標用于反應網絡的聯通程度。

    可以使用該命令來判斷主機與遠程主機是否可達,或之間的網絡是否擁塞。min/avg/max/mdev是ping命令的完成測試后的統計結果,分別表示最小響應時間/平均響應時間/最大響應時間/響應時間方差。這些指標用于反應網絡的聯通程度。

    ping命令執行時,會持續不斷地向目的主機發送ICMP包。在得到對方的應答后,顯示每次連接的統計數據,直到用Ctrl+C組合鍵中斷執行。但是,目前很多主機通過設置防火墻,對ping命令不予應答。在這種情況下,ping命令由于不停地發送測試數據包,又得不到返回任何結果,而致使ping命令僵死。不過,使用-c參數設置發送測試數據包的次數,以便在有限時間內完成測試。

    管理DNS服務器地址

    DNS域名解析可以在更大范圍的計算機網絡、Internet,提供域名到IP地址的轉換。網絡中的每臺計算機都是一個DNS客戶端,向DNS服務器提交域名解析的請求;DNS服務器完成域名到IP地址的映射。
    因此DNS客戶端至少有一個DNS服務器地址,作為命名解析的開端。

    nslookup命令

    使用nslookup命令可以查看當前系統所使用的DNS服務器的IP地址。

    服務器192.168.182.2完成了域名解析。Server表示提供服務的DNS服務器,Address中的#53表示TCP/UDP命名服務的端口號。若所有的DNS服務器都訪問失敗,則出現如下的執行結果。

    D3 Linux shell 腳本編程

    3.1 shell 腳本 變量

    shell腳本的基礎知識

    shell腳本的本質

    編譯型語言
    解釋型語言
    shell腳本語言是解釋型語言 #!/bin/bash (指定shell 類型 )
    shell腳本的本質: shell命令的有序集合

    編程過程

    基本過程分為三步:
    step1. 建立 shell 文件
    包含任意多行操作系統命令或shell命令的文本文件;
    step2. 賦予shell文件執行權限
    用chmod命令修改權限;
    r--read 讀權限 4 w--write 寫權限 2 x--execute 執行權限 1
    step3. 執行shell文件
    直接在命令行上調用shell程序.

    編程過程演示

    shell變量

    shell允許用戶建立變量存儲數據,但不支持數據類型(整型、字符、浮點型),將任何賦給變量的值都解釋為一串字符
    Variable=value

    count=1
    echo $count
    DATE=date
    echo $DATE

    執行 ./filename.sh or bash filename.sh

    Bourne Shell有如下四種變量:
    用戶自定義變量
    位置變量即命令行參數
    預定義變量
    環境變量

    用戶自定義變量

    在shell編程中通常使用全大寫變量,方便識別
    $ COUNT=1
    變量的調用:在變量前加$
    $ echo $HOME
    Linux Shell/bash從右向左賦值,賦值時 ‘=’ 前后不能加空格
    $Y=y
    $ X=$Y
    $ echo $X
    y
    使用unset命令刪除變量的賦值
    $ Z=hello
    $ echo $Z
    hello
    $ unset Z
    $ echo $Z

    命令置換`` 符號不要搞錯,命令置換使用的命令必須有輸出

    位置變量

    $0 與鍵入的命令行一樣,包含腳本文件名
    $1,$2,……$9 分別包含第一個到第九個命令行參數
    $# 包含命令行參數的個數
    $@ 包含所有命令行參數:“$1,$2,……$9”
    $? 包含前一個命令的退出狀態
    $* 包含所有命令行參數:“$1,$2,……$9”
    $$ 包含正在執行進程的ID號

    傳10 個及以上參數,取參 10{10}10{11}${12}…
    特殊符號記得加’'轉義

    環境變量

    HOME: /etc/passwd文件中列出的用戶主目錄
    IFS:Internal Field Separator, 默認為空格,tab及換行符
    PATH :shell搜索路徑
    PS1,PS2:默認提示符($)及換行提示符(>)
    TERM:終端類型,常用的有vt100,ansi,vt200,xterm等

    shell 腳本-功能語句

    shell 程序由零或多條shell語句構成。 shell語句包括三類:說明性語句、功能性語句和結構性語句。
    說明性語句:
    以#號開始到該行結束,不被解釋執行
    功能性語句:
    任意的shell命令、用戶程序或其它shell程序。
    結構性語句:
    條件測試語句、多路分支語句、循環語句、循環控制語句等。

    說明性語句

    說明性語句(注釋行)

    注釋行可以出現在程序中的任何位置,既可以單獨占用一行, 也可以接在執行語句的后面. 以#號開始到所在行的行尾部分,都不被解釋執行. 例如:

    常用功能性語句

    常用功能性語句(命令)

    read從標準輸入讀入一行, 并賦值給后面的變量,其語法為:
    read var
    把讀入的數據全部賦給var
    read var1 var2 var3
    把讀入行中的第一個單詞(word)賦給var1, 第二個單詞賦給var2, ……把其余所有的詞賦給最后一個變量.
    如果執行read語句時標準輸入無數據, 則程序在此停留等侯, 直到數據的到來或被終止運行。
    read -p “輸入提示”

    echo -n 代表不會在最后自動換行
    echo -e 當指定-e選項時,則將解釋反斜杠轉義字符

    應用實例
    # example1 for read echo "Input your name: \c" read username echo "Your name is $username“#example2 for read echo "Input date with format yyyy mm dd: \c" read year month day echo "Today is $year/$month/$day, right?" echo "Press enter to confirm and continue\c" read answer echo "I know the date, bye!"

    算數運算 expr 命令


    expr后邊必須加空格 運算符(+-*/?) 前后必須加空格

    test語句

    test語句可測試三種對象:
    字符串 整數 文件屬性
    每種測試對象都有若干測試操作符
    例如:
    test “$answer” = “yes”
    變量answer的值是否為字符串yes
    test $num –eq 18
    變量num的值是否為整數18
    test -d tmp
    測試tmp是否為一個目錄名

    字符串測試

    s1 = s2 測試兩個字符串的內容是否完全一樣,是返回0
    s1 != s2 測試兩個字符串的內容是否有差異,是返回0
    -z s1 測試s1 字符串的長度是否為0,是返回0
    -n s1 測試s1 字符串的長度是否不為0,是返回0

    整數測試

    舉例子
    1 #!/bin/bash
    2 test 3 -eq 3
    3 echo KaTeX parse error: Expected 'EOF', got '#' at position 4: ? #?`? `包含前一個命令的退出狀態
    a -eq b 測試a 與b 是否相等
    a -ne b 測試a 與b 是否不相等
    a -gt b 測試a 是否大于b
    a -ge b 測試a 是否大于等于b
    a -lt b 測試a 是否小于b
    a -le b 測試a 是否小于等于b

    文件測試

    舉例子:
    #!/bin/bash
    test -f read.sh
    echo $?
    -d name 測試name 是否為一個目錄
    -e name 測試一個文件是否存在
    -f name 測試name 是否為普通文件
    -L name 測試name 是否為符號鏈接
    -r name 測試name 文件是否存在且為可讀
    -w name 測試name 文件是否存在且為可寫
    -x name 測試name 文件是否存在且為可執行
    -s name 測試name 文件是否存在且其長度不為0
    f1-nt f2 測試文件f1 是否比文件f2 更新
    f1-ot f2 測試文件f1 是否比文件f2 更舊
    測試語句記得把test 寫前邊去

    3.2 shell 腳本-結構性語句

    結構性語句主要根據程序的運行狀態、輸入數據、變量的取值、控制信號以及運行時間等因素來控制程序的運行流程。
    主要包括:條件測試語句(兩路分支)、多路分支語句、循環語句、循環控制語句和后臺執行語句等。
    if 條件 then 處理邏輯 fi

    條件語句

    條件語句1

    if…then…fi
    語法結構:
    if 表達式
    then 命令表
    fi
    如果表達式為真, 則執行命令表中的命令; 否則退出if語句, 即執行fi后面的語句。
    if和fi是條件語句的語句括號, 必須成對使用;
    命令表中的命令可以是一條, 也可以是若干條。

    實例

    shell程序prog2.sh(測試命令行參數是否為已存在的文件或目錄)。用法為:
    ./prog2.sh file
    代碼如下:

    #The statement of if…then…fi (注釋語句) if [ -f $1 ] (測試參數是否為文件) thenecho "File $1 exists" (引用變量值) fi if [ -d $HOME/$1 ] (測試參數是否為目錄) then echo "File $1 is a directory" (引用變量值) fi

    執行prog2程序:
    $ ./prog2.sh prog1.sh
    File prog1.sh exists
    $0為prog2.sh; $1為prog1.sh, 是一個已存在的文件.
    $ ./prog2.sh backup
    File backup is a directory
    $0為prog2.sh; $1為backup,是一個已存在的目錄.

    如果不帶參數, 或大于一個參數運行prog2, 例如:
    $ ./prog2.sh (或 $ ./prog2.sh file1 file2)
    會出現什么結果?

    條件語句2

    if…then…else…fi
    語法結構為:
    if 表達式
    then 命令表1
    else 命令表2
    fi
    如果表達式為真, 則執行命令表1中的命令, 再退出if語句; 否則執行命令表2中的語句, 再退出if語句.

    注意: 無論表達式是否為真, 都有語句要執行.

    實例

    test命令的使用

    test命令測試的條件成立時, 命令返回值為真(0),否則返回值為假(非0).

    方式一:test $name -eq $1echo $?方式二:if test -f $filenamethen ……fi方式三:if [ -f $filename ]then ……fi用方括號替代test語句,注意方括號前后至少有一個空格

    實例

    例子: shell程序prog3.sh, 用法為:
    ./prog3.sh file
    內容如下:

    #The statement of if…then…else…fi if [ -d $1 ] thenecho "$1 is a directory"exit #(退出當前的shell程序) else if [ -f $1 ]thenecho "$1 is a common file"elseecho "unknown" fi fi

    運行prog3.sh程序:

    $ ./prog3.sh backup
    backup is a directory

    $ ./prog3.sh prog1
    prog1 is a common file

    $ ./prog3.sh abc
    unknown

    prog3.sh是對prog2.sh的優化, 邏輯結構更加清晰合理!

    shell 布爾運算符

    多路分支語句

    case…esac

    實例

    實例. 程序prog4.sh檢查用戶輸入的文件名, 用法為:
    ./prog4.sh string_name

    # The statement of case…esac if [ $# -eq 0 ] thenecho "No argument is declared"exit fi case $1 infile1)echo "User selects file1";;file2)echo "User selects file2";;*)echo "You must select either file1 or file2!";; esac

    循環語句

    循環語句for的用法

    當循環次數已知或確定時,使用for循環語句來多次執行一條或一組命令。 循環體由語句括號do和done來限定。格式為:

    for 變量名 in 單詞表
    do
    命令表
    done
    變量依次取單詞表中的各個單詞, 每取一次單詞, 就執行一次循環體中的命令. 循環次數由單詞表中的單詞數確定. 命令表中的命令可以是一條, 也可以是由分號或換行符分開的多條。
    如果單詞表是命令行上的所有位置參數時, 可以在for語句中省略 “in 單詞表” 部分。

    實例

    實例:程序prog5.sh拷貝當前目錄下的所有文件到backup子目錄下. 使用語法為: ./prog5.sh [filename]

    #! /bin/bash # for (( i=1; $i <=10 ; i=$i + 1 )) # do # echo "+++ i = $i" # sleep 1; # donefor I in 1 3 5 7 9 doecho "$I" done#for (( ; ; )) #死循環 #do # echo "+++" # echo "---" #done

    while循環

    語法結構為:
    while 命令或表達式
    do
    命令表
    done
    while語句首先測試其后的命令或表達式的值,如果為真,就執行一次循環體中的命令,然后再測試該命令或表達式的值,執行循環體,直到該命令或表達式為假時退出循環。
    while語句的退出狀態為命令表中被執行的最后一條命令的退出狀態。

    實例

    創建文件程序prog6, 批量生成空白文件,用法為:
    prog6 file [number] ./a.sh file 6

    循環控制語句

    break 和 continue
    break n 則跳出n層;
    continue語句則馬上轉到最近一層循環語句的下一輪循環上,
    continue n則轉到最近n層循環語句的下一輪循環上.
    實例. 程序prog7的用法為:
    prog7 整數 整數 整數 …
    參數個數不確定, 范圍為1~10個, 每個參數都是正整數。

    3.3 shell 腳本-函數

    shell函數調用

    實例

    check_user( ) { #查找已登錄的指定用戶user=`who | grep $1 | wc -l`if [ $user –eq 0 ]thenreturn 0 #未找到指定用戶elsereturn 1 #找到指定用戶fi } while true # MAIN, Main, main: program begin here doecho "Input username: \c"read unamecheck_user $uname # 調用函數, 并傳遞參數unameif [ $? –eq 1 ] # $?為函數返回值then echo "user $uname online"else echo "user $uname offline"fi done

    函數變量作用域

    全局作用域:在腳本的其他任何地方都能夠訪問該變量。
    局部作用域:只能在聲明變量的作用域內訪問。
    聲明局部變量的格式:
    Local variable_name =value

    #!/bin/bash Scope() {local lclvariable=1Gblvariable=2echo "lclavariable in function = $lclvariable"echo "Gblvariable in function = $Gblvariable" }Scopeecho "lclavariable in function = $lclvariable" echo "Gblvariable in function = $Gblvariable"

    結果

    $(1-9)放函數內部,表示函數參數,不再是名令行參數
    注意方法內的變量默認是全局的,局部變量需要加local 修飾。

    D4 Linux C高級語言編程

    4.1 gcc 編譯器和gdb

    gcc 編譯器

    GNU工具

    編譯工具:把一個源程序編譯為一個可執行程序
    調試工具:能對執行程序進行源碼或匯編級調試
    軟件工程工具:用于協助多人開發或大型軟件項目的管理,如make、CVS、Subvision
    其他工具:用于把多個目標文件鏈接成可執行文件的鏈接器,或者用作格式轉換的工具。

    部分相關資源

    http://www.gnu.org/
    http://gcc.gnu.org/
    http://www.kernel.org/
    http://www.linux.org/
    http://www.linuxdevices.com/
    http://sourceforge.net/index.php

    GCC簡介

    全稱為GNU CC ,GNU項目中符合ANSI C標準的編譯系統
    編譯如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多種語言
    GCC是可以在多種硬體平臺上編譯出可執行程序的超級編譯器,其執行效率與一般的編譯器相比平均效率要高20%~30%
    一個交叉平臺編譯器 ,適合在嵌入式領域的開發編譯

    GCC編譯器的版本

    GNU Compiler Collection
    C, C++, Objective-C, Fortran, Java, Ada
    http://gcc.gnu.org

    gcc所支持后綴名解釋

    .c C原始程序 .C/.cc/.cxx C++原始程序 .h 預處理文件(頭文件) .i 已經過預處理的C原始程序 .ii 已經過預處理的C++原始程序 .s/.S 匯編語言原始程序 .o 目標文件 .a/.so 編譯后的庫文件

    編譯器的主要組件

    分析器:分析器將源語言程序代碼轉換為匯編語言。因為要從一種格式轉換為另一種格式(C到匯編),所以分析器需要知道目標機器的匯編語言。
    匯編器:匯編器將匯編語言代碼轉換為CPU可以執行字節碼。
    鏈接器:鏈接器將匯編器生成的單獨的目標文件組合成可執行的應用程序。鏈接器需要知道這種目標格式以便工作。
    標準C庫:核心的C函數都有一個主要的C庫來提供。如果在應用程序中用到了C庫中的函數,這個庫就會通過鏈接器和源代碼連接來生成最終的可執行程序

    GCC的基本用法和選項

    Gcc最基本的用法是∶gcc [options] [filenames]
    -c,只編譯,不連接成為可執行文件,編譯器只是由輸入的.c等源代碼文件生成.o為后綴的目標文件,通常用于編譯不包含主程序的子程序文件。
    -o output_filename,確定輸出文件的名稱為output_filename,同時這個名稱不能和源文件同名。如果不給出這個選項,gcc就給出預設的可執行文件a.out。
    -g,產生符號調試工具(GNU的gdb)所必要的符號資訊,要想對源代碼進行調試,我們就必須加入這個選項。
    -O,對程序進行優化編譯、連接,采用這個選項,整個源代碼會在編譯、連接過程中進行優化處理,這樣產生的可執行文件的執行效率可以提高,但是,編譯、連接的速度就相應地要慢一些。
    -O2,比-O更好的優化編譯、連接,當然整個編譯、連接過程會更慢。
    -I dirname,將dirname所指出的目錄加入到程序頭文件目錄列表中,是在預編譯過程中使用的參數。
    -L dirname,將dirname所指出的目錄加入到程序函數檔案庫文件的目錄列表中,是在鏈接過程中使用的參數。
    GCC 全稱為GNU CC ,GNU項目中符合ANSI C標準的編譯系統,編譯如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多種語言

    GCC的錯誤類型及對策

    第一類∶C語法錯誤
    錯誤信息∶文件source.c中第n行有語法錯誤(syntex errror)。有些情況下,一個很簡單的語法錯誤,gcc會給出一大堆錯誤,我們最主要的是要保持清醒的頭腦,不要被其嚇倒,必要的時候再參考一下C語言的基本教材。
    第二類∶頭文件錯誤
    錯誤信息∶找不到頭文件head.h(Can not find include file head.h)。這類錯誤是源代碼文件中的包含頭文件有問題,可能的原因有頭文件名錯誤、指定的頭文件所在目錄名錯誤等,也可能是錯誤地使用了雙引號和尖括號。
    第三類∶檔案庫錯誤
    錯誤信息∶鏈接程序找不到所需的函數庫(ld: -lm: No such file or directory )。這類錯誤是與目標文件相連接的函數庫有錯誤,可能的原因是函數庫名錯誤、指定的函數庫所在目錄名稱錯誤等,檢查的方法是使用find命令在可能的目錄中尋找相應的函數庫名,確定檔案庫及目錄的名稱并修改程序中及編譯選項中的名稱。
    第四類∶未定義符號
    錯誤信息∶有未定義的符號(Undefined symbol)。
    這類錯誤是在鏈接過程中出現的,可能有兩種原因∶一是使用者自己定義的函數或者全局變量所在源代碼文件,沒有被編譯、連接,或者干脆還沒有定義;二是未定義的符號是一個標準的庫函數,在源程序中使用了該庫函數,而連接過程中還沒有給定相應的函數庫的名稱,或者是該檔案庫的目錄名稱有問題,這時需要使用檔案庫維護命令ar檢查我們需要的庫函數到底位于哪一個函數庫中,確定之后,修改gcc連接選項中的-l和-L項。

    GCC使用實例

    #include<stdio.h> int main(void) { int i,j; j=0; i=j+1; printf(“hello,world\n”); printf(“the result is %d\n”,i); } 編譯:gcc -0 test test.c 執行: ./test 查看更詳細的信息:gcc -v -o test.c

    GCC編譯過程

    GCC的編譯流程分為四個步驟:
    預處理(Pre-Processing)
    編譯(Compiling)
    匯編(Assembling)
    鏈接(Linking)

    “hello”的演變歷程

    生成預處理代碼
    gcc -E test.c -o tset.i用wc 命令,查看兩個階段代碼大小 wc test.c test


    test.i比test.c增加了很多內容,主要是放在系統提供的include文件中的。

    生成匯編代碼

    檢查語法錯誤,并生成匯編文件
    gcc -S test.i -o test.s

    生成目標代碼
    方法一,直接從C源代碼中生成目標代碼 gcc -c test.c -o test.o方法二,用匯編器從匯編代碼生成目標代碼 as test.s -o test.o
    生成可執行程序

    將目標程序鏈接庫資源,生成可執行程序
    gcc test.o -o test
    ./test

    GDB調試工具

    調試器–Gdb調試流程

    首先使用gcc對test.c進行編譯,注意一定要加上選項‘-g’

    流程

    查看文件 l
    查看變量值p n
    設置斷點 b 6
    單步運行 n | s
    查看斷點情況 info b
    恢復程序運行 c
    運行代碼 r
    幫助 help

    Gdb的使用切記點

    編譯必須加入-g
    只有在代碼處于運行或暫停狀態時才能查看變量值
    設置斷點后程序在指定行之前停止
    gdb filename 進入調試模式

    4.2 C語言高級編程-條件編譯和結構體

    條件編譯

    編譯器根據條件的真假決定是否編譯相關的代碼

    一、根據宏是否定義,其語法如下:

    #ifdef <macro>……#else……#endif #define _DEBUG_ #ifdef _DEBUG_ printf(“The macro _DEBUG_ is defined\n”); #else printf(“The macro _DEBUG_ is not defined\n”); #endif

    注意:#ifdef 可以寫成 #ifndef 則功能相反

    二、根據宏的值,其語法如下

    #if <macro> …… #else …… #endif #define _DEBUG_ 1 #if _DEBUG_ printf(“The macro _DEBUG_ is defined\n”); #else printf(“The macro _DEBUG_ is not defined\n”); #endif

    三、gcc 時宏的定義

    在gcc中, 可在命令行中指定對象宏的定義:
    e.g.
    $ gcc -Wall -DMAX=100 -o tmp tmp.c
    相當于在tmp.c中添加" #define MAX 100".

    那么, 如果原先tmp.c中含有MAX宏的定義, 那么再在gcc調用命令中使用-DMAX, 會出現什么情況呢?
    —若-DMAX=1, 則正確編譯.
    —若-DMAX的值被指定為不為1的值, 那么gcc會給出MAX宏被重定義的警告, MAX的值仍為1.
    注意: 若在調用gcc的命令行中不顯示地給出對象宏的值, 那么gcc賦予該宏默認值(1), 如: -DVAL == -DVAL=1

    D5 Makefile

    5.1 Make介紹

    Make簡介

    工程管理器,顧名思義,是指管理較多的文件
    Make工程管理器也就是個“自動編譯管理器”,這里的“自動”是指它能夠根據文件時間戳自動發現更新過的文件而減少編譯的工作量,同時,它通過讀入Makefile文件的內容來執行大量的編譯工作
    Make將只編譯改動的代碼文件,而不用完全編譯。

    Makefile基本結構

    Makefile是Make讀入的唯一配置文件
    由make工具創建的目標體(target),通常是目標文件或可執行文件
    要創建的目標體所依賴的文件(dependency_file)
    創建每個目標體時需要運行的命令(command)
    注意:命令行前面必須是一個”TAB鍵”,否則編譯錯誤為:*** missing separator. Stop.

    Makefile格式
    target : dependency_files
    command
    例子

    hello.o : hello.c hello.hgcc –c hello.c –o hello.o

    一個復雜一些的例子

    sunq:kang.o yul.ogcc kang.o yul.o -o sunq kang.o : kang.c kang.h gcc –Wall –O -g –c kang.c -o kang.o yul.o : yul.c gcc - Wall –O -g –c yul.c -o yul.o

    注釋:-Wall:表示允許發出gcc所有有用的報警信息.
    -c:只是編譯不鏈接,生成目標文件”.o”
    -o file:表示把輸出文件輸出到file里

    Makefile 注釋符

    # 字符是注釋符
    makefile 把 # 字符后面的內容作為注釋內容處理(shell、perl 腳本也是使用 # 字符作為注釋符)。
    如果某行的第一個非空字符為 #,則此行會被 make 解釋為注釋行(命令行除外,如果 Tab 字符之后使用 # 字符,則會被 make 解釋為命令行。
    注釋行的結尾如果存在反斜線(\),那么下一行也被作為注釋行。

    Makefile變量

    創建和使用變量

    創建變量的目的:用來代替一個文本字符串:

    1. 系列文件的名字 2. 傳遞給編譯器的參數 3. 需要運行的程序 4. 需要查找源代碼的目錄 5. 你需要輸出信息的目錄 6. 你想做的其它事情。

    變量定義的兩種方式
    遞歸展開方式VAR=var
    簡單方式 VAR := var

    變量使用 $(VAR)

    用””則用””則用”則用$”來表示
    類似于編程語言中的宏

    剛才的例子

    OBJS = kang.o yul.o CC = gcc CFLAGS = -Wall -O -g sunq : $(OBJS)$(CC) $(OBJS) -o sunq kang.o : kang.c kang.h$(CC) $(CFLAGS) -c kang.c -o kang.o yul.o : yul.c yul.h$(CC) $(CFLAGS) -c yul.c -o yul.o
    遞歸展開方式VAR=var

    例子:
    foo = $(bar)
    bar = $(ugh)
    ugh = Huh?
    $(foo)的值為?
    echo $(foo)來進行查看
    優點:
    它可以向后引用變量
    缺點:
    不能對該變量進行任何擴展,例如
    CFLAGS = $(CFLAGS) -O
    會造成死循環

    簡單方式:VAR:=var
    m := mm x := $(m) y := $(x) bar x := later all:echo $(x) $(y)

    linux@linux:~/file/tmp$ make
    echo later mm bar
    later mm bar

    用這種方式定義的變量,會在變量的定義點,按照被引用的變量的當前值進行展開
    這種定義變量的方式更適合在大的編程項目中使用,因為它更像我們一般的編程語言

    用?=定義變量
    dir := /foo/bar
    FOO ?= bar

    FOO是?

    含義是,如果FOO沒有被定義過,那么變量FOO的值就是“bar”,如果FOO先前被定義過,那么這條語將什么也不做,其等價于:
    ifeq ($(origin FOO), undefined)
    FOO = bar
    endif

    為變量添加值
    你可以通過+=為已定義的變量添加新的值
    Main=hello.o hello-1.o
    Main+=hello-2.o

    特殊變量

    預定義變量

    AR 庫文件維護程序的名稱,默認值為ar。AS匯編程序的名稱,默認值為as。
    CC C編譯器的名稱,默認值為cc。CPP C預編譯器的名稱,默認值為$(CC) –E。
    CXX C++編譯器的名稱,默認值為g++。
    FC FORTRAN編譯器的名稱,默認值為f77
    RM 文件刪除程序的名稱,默認值為rm -f
    例子:
    Hello: main.c main.h
    $(CC) –o hello main.c
    clean:
    $(RM) hello

    其他預定義變量
    ARFLAGS 庫文件維護程序的選項,無默認值。
    ASFLAGS 匯編程序的選項,無默認值。
    CFLAGS C編譯器的選項,無默認值。
    CPPFLAGS C預編譯的選項,無默認值。
    CXXFLAGS C++編譯器的選項,無默認值。
    FFLAGS FORTRAN編譯器的選項,無默認值。

    剛才的例子
    OBJS = kang.o yul.o
    CC = gcc
    CFLAGS = -Wall -O -g
    sunq : $(OBJS)
    $(CC) $(OBJS) -o sunq
    kang.o : kang.c kang.h
    $(CC) $(CFLAGS) -c kang.c -o kang.o
    yul.o : yul.c yul.h
    $(CC) $(CFLAGS) -c yul.c -o yul.o

    自動變量

    $* 不包含擴展名的目標文件名稱
    $+ 所有的依賴文件,以空格分開,并以出現的先后為序,可能 包含重復的依賴文件
    $< 第一個依賴文件的名稱
    $? 所有時間戳比目標文件晚的的依賴文件,并以空格分開
    $@ 目標文件的完整名稱
    $^ 所有不重復的目標依賴文件,以空格分開
    $% 如果目標是歸檔成員,則該變量表示目標的歸檔成員名稱

    make運行環境變量

    make在啟動時會自動讀取系統當前已經定義了的環境變量,并且會創建與之具有相同名稱和數值的變量
    如果用戶在Makefile中定義了相同名稱的變量,那么用戶自定義變量將會覆蓋同名的環境變量

    直接運行make
    選項
    -C dir讀入指定目錄下的Makefile
    -f file讀入當前目錄下的file文件作為Makefile
    -I 忽略所有的命令執行錯誤
    -I dir指定被包含的Makefile所在目錄
    -n 只打印要執行的命令,但不執行這些命令
    -p 顯示make變量數據庫和隱含規則
    -s 在執行命令時不顯示命令
    -w 如果make在執行過程中改變目錄,打印當前目錄名

    靜態模式1

    Makefile 靜態模式——$(objects): %.o: %.c

    靜態模式+自動化變量

    舉例

    objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@

    等價于?

    foo.o : foo.c $(CC) -c $(CFLAGS) foo.c -o foo.o bar.o : bar.c $(CC) -c $(CFLAGS) bar.c -o bar.o

    偽目標

    test:f1.o f2.o main.ogcc f1.o f2.o main.o -o test f2.o:f2.cgcc -c f2.c -o f2.o f1.o:f1.cgcc -c f1.c -o f1.o main.o:main.cgcc -c main.c -o main.o .PHONY:clean // 將clean 定義為偽目標,表明claen 不是一個可執行文件,避免在同級目錄存在同名文件時,make 報錯: clean:rm *.o test

    設置偽目標前:

    設置偽目標后:

    Makefile的隱含規則

    隱含規則1:編譯C程序的隱含規則
    “.o”的目標的依賴目標會自動推導為“.c”,并且其生成命令是“$(CC) –c $(CPPFLAGS) $(CFLAGS)”

    隱含規則2:鏈接Object文件的隱含規則
    “” 目標依賴于“.o”,通過運行C的編譯器來運行鏈接程序生成(一般是“ld”),其生成命令是:“$(CC) $(LDFLAGS) .o $(LOADLIBES) $(LDLIBS)”。這個規則對于只有一個源文件的工程有效,同時也對多個Object文件(由不同的源文件生成)的也有效。例如如下規則:
    x : x.o y.o z.o
    并且“x.c”、“y.c”和“z.c”都存在時,隱含規則將執行如下命令:
    cc -c x.c -o x.o
    cc -c y.c -o y.o
    cc -c z.c -o z.o
    cc x.o y.o z.o -o x
    如果沒有一個源文件(如上例中的x.c)和你的目標名字(如上例中的x)相關聯,那么,你最好寫出自己的生成規則,不然,隱含規則會報錯的。

    生成多個可執行文件

    makefile 默認只生成第一個可執行文件,所以為了同時編譯多個可執行文件,我們用到了偽可執行文件,make 過程中并不生成 這個偽可執行文件,利用依賴的屬性,同時生成三個可執行文件

    all : init sender receiver .PHONY : clean init : init.o common.occ -pthread -o init init.o common.o sender : sender.o common.occ -pthread -o sender sender.o common.o receiver : receiver.o common.occ -pthread -o receiver receiver.o common.o init.o : common.h sender.o : common.h receiver.o : common.h clean : rm init rm receiverrm sender rm *.o

    5.2 make命令的選項及Make

    使用make 管理器非常簡單,只需在make 命令的后面鍵入目標名即可建立指定的目標。如果直接運行make,則建立Makefile中的第一個目標。
    命令行選項:

    -C dir讀入指定目錄下的Makefile -f file讀入當前目錄下的file文件作為Makefile -i忽略所有的命令執行錯誤 -I dir指定被包含的Makefile所在目錄 -n只打印要執行的命令,但不執行這些命令 -p顯示make變量數據庫和隱含規則 -s在執行命令時不顯示命令 -w如果make在執行過程中改變目錄,打印當前目錄名

    5.3 VPATH及嵌套的Makefile

    Makefile的VPATH

    VPATH : 虛路徑
    在一些大的工程中,有大量的源文件,我們通常的做法是把這許多的源文件分類,并存放在不同的目錄中。所以,當make需要去找尋文件的依賴關系時,你可以在文件前加上路徑,但最好的方法是把一個路徑告訴make,讓make在自動去找。
    Makefile文件中的特殊變量“VPATH”就是完成這個功能的,如果沒有指明這個變量,make只會在當前的目錄中去找尋依賴文件和目標文件。如果定義了這個變量,那么,make就會在當當前目錄找不到的情況下,到所指定的目錄中去找尋文件了。

    VPATH = src:…/headers
    上面的的定義指定兩個目錄,“src”和“…/headers”,make會按照這個順序進行搜索。目錄由“冒號”分隔。(當然,當前目錄永遠是最高優先搜索的地方)

    案例

    CC=gcc CFLAGS=-c -Wall -I include VPATH=src1:src2:main f1:f1.o f2.o main.o$(CC) $(CFLAGS) $^ -o $@ .PHONY:clean clean:find ./ -name "*.o" -exec rm {} \;;rm f1

    'linux中的 exec命令,-exec 后面跟的是linux的 command 命令,exec命令以分號結束‘;’, 該分號前面要放反斜杠轉義 。{} 花括號代表前面的命令執行的結果

    Makefile的嵌套

    我們注意到有一句@echo $(SUBDIRS)
    @echo off 的意思是關閉回顯,不顯示正在執行的批處理命令及執行的結果等。
    語法:echo [{on off}] [message] 示例:@echo off / echo hello world。
    當echo設置off值的時候,那么下面的指令都將只執行而不顯示,當再次出現echo on時下面的語句才為可見的(回顯)。
    echo通常和@一起使用,@放在echo的前面,即是 @echo,作用是讓@后面的句子不顯示出來,而@本身也是不顯示的
    通過 @echo off 可達到不顯示任何信息的效果。

    @(RM)并不是我們自己定義的變量,那它是從哪里來的呢?
    預定義變量 : RM 文件刪除程序的名稱,默認值為rm -f
    make -C @‘?Cdir讀入指定目錄下的Makefile‘‘@ ` -C dir讀入指定目錄下的Makefile` `@‘?Cdir讀入指定目錄下的Makefile‘‘@ ——目標文件的名稱`

    課程案例

    工程文件如下:

    可以看主Makefile文件內容如下

    CC=gcc #同一行命令換行結尾加 '\' 聲明未結束。 SUBDIRS=f1 \f2 \main \obj OBJS=f1.o f2.o main.o BIN=myapp OBJS_DIR=obj BIN_DIR=bin #export的作用是將變量傳遞給子目錄下的Makefile文件以供它們使用 export CC OBJS BIN OBJS_DIR BIN_DIRall:CHECK_DIR $(SUBDIRS) CHECK_DIR:mkdir -p $(BIN_DIR) $(SUBDIRS):ECHOmake -C $@ ECHO:@echo $(SUBDIRS)@echo begin compile CLEAN:@$(RM) $(OBJS_DIR)/*.o@rm -rf $(BIN_DIR)

    其他案例:

    在一些大的工程中,我們會把我們不同模塊或是不同功能的源文件放在不同的目錄中,我們可以在每個目錄中都書寫一個該目錄的 Makefile,這有利于讓我們的 Makefile 變得更加地簡潔,而不至于把所有的東西全部寫在一個 Makefile 中,這樣會很難維護我們的 Makefile,這個技術對于我們模塊編譯和分段編譯有著非常大的好處。
    工程文件如下

    可以看主makefile文件內容如下

    CC =gccTOP_DIR :=$(PWD) INCLUDE :=$(TOP_DIR)/headers SRC_DIR :=$(TOP_DIR)/src APP_DIR :=$(TOP_DIR)/app VPATH := $(SRC_DIR):$(APP_DIR) CFLAGS = -I $(INCLUDE)export CC VPATH CFLAGS.PHONY:all clean all:$(MAKE) -C $(SRC_DIR)$(MAKE) -C $(APP_DIR) clean:$(MAKE) -C $(SRC_DIR) clean$(MAKE) -C $(APP_DIR) clean

    其中$(MAKE) -C (SRCDIR)是到對應的子目錄下執行make,使用(SRC_DIR)是到對應的子目錄下執行make,使用(SRCD?IR)是到對應的子目錄下執行make,使用(MAKE)是為了方便以后可以添加適當的make參數,-C參數是在進入或者退出目錄時打印出來。
    export的作用是將變量傳遞給子目錄下的Makefile文件以供它們使用。

    版權聲明:本文為CSDN博主「juruiyuan111」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
    原文鏈接:https://blog.csdn.net/juruiyuan111/article/details/119894932

    注腳

    ?


  • 這個靜態模式就是一種自動編譯模式,在這種模式下,我們可以容易的定義“多目標”規則,讓我們的規則變得更加有彈性和靈活。它的語法如下:
    < targets …> : < target-pattern > : < prereq-patterns …>
    <commands>

    其中:
    targets定義了一些列的目標文件,也就是多目標,可以有通配符,是目標的一個集合。
    target-pattern 是targets的模式,也就是目標集模式
    prereq-patterns 則是目標的“依賴”元素,
    這么去說,可能還是比較拗口,不容易理解,我們還是把理論落地,舉例一下吧:
    我們把target-pattern 定義成 %.o 意思是我們的target集合都是以.o結尾。當然這里也可以使用通配符*,只不過%多用于Makefile,他們兩個的區別,我們后面再講。而我們的prereq-patterns則定義為%.c,這意思就是對 target-pattern中所形成的目標集進行二次定義,其計算方法是取target-pattern模式中的%代表部分(其實就是去掉.o后的文件名),并為其加上[.c]結尾,形成新的集合。
    ————————————————
    版權聲明:本文為CSDN博主「豬哥-嵌入式」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
    原文鏈接:https://blog.csdn.net/u012351051/article/details/88600562 ??

  • 總結

    以上是生活随笔為你收集整理的LV.2 Linux C语言高级的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲精品国产电影 | 91动态图 | 色视频一区二区 | 黄页嫩草 | 在哪里看毛片 | 成人激情小视频 | 三级av在线播放 | 狠狠躁日日躁夜夜躁2022麻豆 | 97精品人妻一区二区三区蜜桃 | 中文字幕一区二区三区在线观看 | 亚洲精品国产精品国自产网站按摩 | 日本少妇毛茸茸高潮 | 色婷婷av一区二区三区gif | 久久精品99国产精 | 免费三片在线观看网站v888 | 扒开美女内裤狂揉下部 | 影音先锋中文字幕在线 | 国内成人精品视频 | 国产精品丝袜黑色高跟鞋的设计特点 | 亚洲美女视频 | 91国产视频在线 | 可以免费看毛片的网站 | 三级免费黄| 拔擦8x成人一区二区三区 | 91网在线播放 | 免费操片 | 国产精品探花一区二区在线观看 | 欧美日韩国产三级 | 日韩高清一级片 | 中文字幕第100页 | 阿拉伯性视频xxxx | 第一色综合 | 18在线观看免费入口 | 亚州精品毛片 | 国产成人亚洲欧洲在线 | 香蕉视频在线免费播放 | 麻豆精品视频在线观看 | 综合久色 | 去毛片| youjizz.com国产 | 精品一区二区三区在线视频 | 色哟哟一区 | 国产喷潮 | 俄罗斯厕所偷拍 | 国产一级一片免费播放 | 丰满人妻在公车被猛烈进入电影 | 国产一区二区三区免费播放 | 黄色一级网站 | 五月天婷婷激情 | 丰满岳妇乱一区二区三区 | 亚洲视频在线观看网站 | 人人爱人人草 | 国产一区二区三区四区五区在线 | 国产乡下妇女做爰 | 欧美色国 | 国产精品成人免费精品自在线观看 | 日本不卡视频在线观看 | 国产乱人伦| 成人交性视频免费看 | 亚洲国产精品久久 | 在线观看免费日韩av | 性色视频在线 | 中文天堂资源在线 | 香蕉视频官网在线观看 | 国产一级二级三级在线观看 | 成人aaa| 亚洲精品在线免费看 | 久久999| 天天碰天天摸 | 夜色一区二区三区 | 国语对白一区二区三区 | 久久精品这里只有精品 | 四虎影视成人 | 俄罗斯色片 | 二区三区偷拍浴室洗澡视频 | www激情| 日韩免费淫片 | 国产精品久久久久久久午夜 | 黄页网站视频 | 一区精品二区国产 | 亚洲乱码在线观看 | 99精品免费视频 | 污网站在线播放 | 国产精品高潮呻吟久久久 | av女星全部名单 | 国产盗摄一区二区三区在线 | 日韩精品影视 | 免费黄色网页 | 久久久久久一区二区三区 | 国产精品亚洲无码 | 黄色观看网站 | 漂亮人妻被中出中文字幕 | 亚洲成人av网址 | 蜜臀少妇久久久久久久高潮 | 妺妺窝人体色WWW精品 | 中文有码av| 国产又大又黑又粗 | 亚洲一区中文字幕 | a级无遮挡超级高清-在线观看 |