Linux系統初識

本文主要內容:計算即架構,軟件與硬件基礎,Linux歷史、哲學思想等,以及FHS

Linux是一個操作系統(Operating System),主要負責分配底層硬件的抽象能力,協調各個程序的運行的程序1

然而對於剛入門的我們而言,這個回答似乎並沒有讓我們明白,遂本文章將從最基礎的概念開始說起,說明該問題。

其實我曾一直有一個疑問,爲什麼大部分的書籍都會在第一章介紹歷史,大部分人對此並不是特別關心,“浪費”時間去讀這些有必要嗎?現在認爲是有必要的,就如前面已經回答了Linux是什麼的問題,但是新人依然一知半解,瞭解一下環境與歷史可以直接減小我們對於一個新事物的畏懼(竊以爲該畏懼幾乎全部來自於未知!)Linux

一、操作系統基礎

1. 計算機硬件

1.1 馮·諾依曼結構

馮·諾依曼結構(Von Neumann architecture)是一種將程序指令存儲器和數據存儲器合併在一起的計算機設計概念結構。現代的計算機系統(包括手機等便攜式終端)的基礎架構幾乎都是以此設計的,其結構如下:
馮·諾依曼結構
根據該體系,計算機硬件分爲5部分:

  • 運算器(Arithmetic Logic Unit
  • 控制器(Control Unit
  • 存儲器(Memory
  • 輸入設備(Input
  • 輸出設備(Output

我們通常意義上的所謂的 CPU(Center Processing Unit) 事實上負責的就是運算器與控制器的工作,他就像動物的大腦一樣,計算數據,發送各種控制指令,其主要運算工作有其內部的一個非常重要的部件 累加器(Accumulator) 完成;控制工作主要由總線對外傳輸(後續會詳細說明)

CPU運算數據的來源或結果,將存儲在存儲器中,即我們所說的 內存(Memory) 。衆所周知,目前的計算機幾乎都是由電來驅動,故內存在計算機斷點後將無法保存數據。以上三項構成了計算機最核心的部件。

輸入設備與輸出設備,我們通常將其和稱爲 I/O(Input/Output)設備 ,負責計算機與外界交互,如將計算結果輸出到屏幕,或錄入數據,如打字,相信很好理解。2

1.2 CPU緩存

由於技術工藝原因,存儲器(內存)的速度與CPU的速度差距甚遠,由此CPU在與內存交互式將產生嚴重的性能浪費,即 馮·諾伊曼瓶頸:

Surely there must be a less primitive way of making big changes in the store than by pushing vast numbers of words back and forth through the von Neumann bottleneck. Not only is this tube a literal bottleneck for the data traffic of a problem, but, more importantly, it is an intellectual bottleneck that has kept us tied to word-at-a-time thinking instead of encouraging us to think in terms of the larger conceptual units of the task at hand. Thus programming is basically planning and detailing the enormous traffic of words through the von Neumann bottleneck, and much of that traffic concerns not significant data itself, but where to find it.2

鑑於此,我們在CPU芯片內部開闢了一小部分空間,用來存儲與CPU頻繁通信的數據,甚至根據數據與CPU通信的頻繁程度等因素的不同而存儲在不同的區域,這就是 CPU緩存(CPU Cache) 。根據寄存器與CPU核心的“距離”將其分爲一級緩存、二級緩存等。

一般而言,緩存等級越小,代表其與CPU核心越近,速度也就越快,由於其在“繁華地段”,空間也就越小,造價亦是越高。

1.3 寄存器

雖然在計算機體系結構中存在有存儲器,但是運算器與控制器在運行時依然需要將數據臨時存儲。在CPU內部有各種用於存儲數據的空間,專門用於存儲數據或指令,即寄存器(Register)。

一般而言,計算機存儲部件的速度爲:寄存器(可以CPU同頻率工作)> 一級緩存 > 二級緩存 > … > 內存

2. 計算機軟件

官方一點講,我們所謂的“計算機”指的是計算機硬件與軟件,純計算機硬件只能根據自然現象做無意義的響應。這就需要我們制定相應的邏輯去幹預。而如何制定合理邏輯,如何讓冰冷的機器理解,以及如何讓其高效準確地執行,這就是軟件需要考慮的問題。

2.1 二進制

由於計算機是由 電能驅動 ,那麼如何讓計算機能理解我們的信息(數據)並處理就是要面對的首要問題。

很容易聯想到的一個方案就是用電流或電壓的大小來表示數據:1V表示1,2V表示2……那麼要表示從地球到月球有多少米呢?這種方式有點耗能量,也有點危險……

換一個思路,我們使用一個開關來控制“有電”或者“沒有電”,有電錶示1,沒有電錶示0。那麼在存儲數據時,可以抽象地理解爲通過該存儲單元是否有電(1或0)來表示信息。

由此,可以使用兩個狀態來表示各種數據(只要空間夠大)。比如現在有8個存儲單位,分別都可以表示0或1,那麼這些單位組合起來一共可以表示 28 種不同的狀態。每一個存儲單位叫做位(bit),這8位空間就叫做一個字節(Byte)

按照計數基本方法,我們將使用2個數字來表示各種數據,這就是 二進制(Binary),類比十進制,二進制逢二進一,那麼十進制的2,用二進制將表示爲10。

以下爲十進制數字與二進制數字的簡要對照,供初學者理解3

十進制 32 16 10 9 8 7 6 5 4 3 2 1 0
二進制 100000 10000 1010 1001 1000 111 110 101 100 11 10 1 0

2.2 程序

機器語言

由於計算機底層只能理解二進制數,故欲傳達指令,也是使用由01組合的數字爲媒介,這就需要機器能理解指令。計算機芯片在誕生之時,該能力已經由生產廠商賦予。開發人員按照廠商所給的“語法”進行開發,這就是機器語言(Machine Language)。

隨着社會的發展,計算機要解決的問題越來越複雜,是用該方式開發的弊端暴露無遺:機器語言人類太難直觀理解,開發、調試、修改困難。

彙編語言

爲了解決以上問題,廠商將該“語法”進行了升級,用簡單的單詞縮寫來代替二進制代碼,即彙編語言(Assembly Language),如此一來大大減小了開發難度(相對而言)。

彙編語言雖然提高了人類對於開發語言的理解,但是依然非常底層(即邏輯接近機器),開發程序需要學習大量計算機理論,門檻較高,同時依然面對與機器語言相同的問題,不易於維護。

高級語言

高級語言是以人類的日常語言爲基礎的一種編程語言,使用一般人易於接受的文字來表示,有較高的可讀性,以方便對計算機認知較淺的人亦可以大概明白其內容。

高級語言與計算機的硬件結構及指令系統無關,它有更強的表達能力,可方便地表示數據的運算和程序的控制結構,能更好的描述各種算法,而且容易學習掌握。但高級語言編譯生成的程序代碼一般比用匯編程序語言設計的程序代碼要長,執行的速度也慢。所以彙編語言適合編寫一些對速度和代碼長度要求高的程序和直接控制硬件的程序。這裏所謂的“高級”的意義是距離人類邏輯較近,即更易理解。

2.3 操作系統

由於不同的硬件廠商生產的產品不同,所給的語法(即指令集(ISA))不同,使用匯編開發的程序移植性很差,而高級語言最終也需要轉爲機器語言纔可讓硬件理解,並且即使是同一個機器上的不同程序,也會有大量的相同邏輯,來負責硬件資源調度等基本工作,以提供一個可能執行業務計算的前提。由此就迫切需要一個通用的代碼,負責與底層硬件交互,爲應用程序提供運行環境。

這就是現代操作系統(Operating System)的主要任務之一。它彌合了底層硬件的差異,對上層提供一致的接口與規範。比如如何讓讀取數據,如何驅動聲卡發聲等。程序可以直接調用該庫進行工作,即系統調用

由於系統調用雖然提供了相關能力,但是依然太過於底層,僅僅使用系統調用的方式開發應用程序太過於困難,對於程序員的學習要求也過高。故一個完整的系統一般會在用戶空間將系統調用再次封裝,使之成爲有實際作用的接口,封裝後的接口通常以C庫的方式對外提供。即API(Application Programming Interface),程序員可使用這些庫調用進行開發,也可以直接使用系統調用,實現更能靈活的代碼操作。

操作系統的另一個任務就是要協調各個應用。計算機底層實質上是一堆邏輯電路的組合,故在某一刻只能執行一項運算,隨着硬件運算能力的提升,這種機制對於計算能力的浪費是巨大的。這就需要程序有一個約定好的“規則”,以確定如何使用硬件資源。

操作系統可以作爲“監控者”,合理分配運算與存儲資源給各個應用程序。同時,其還提供其他能力,如,將通用的功能封裝爲接口,以供程序調用。

目前主流的操作系統有:

  • Windows,個人電腦主流操作系統,VMS內核
  • MacOS,蘋果公司生產的Mac電腦操作系統,FreeBSD內核
  • Linux,服務器或商業主流操作系統,擁有衆多發行版
  • Android,移動終端主流操作系統,實質上是運行在Linux之上的Java虛擬機
  • IOS,蘋果公司生產的移動終端操作系統,流暢高效

二、Linux基礎介紹

1. Linux歷史簡介

上文提到的操作系統已經是較爲成熟的產品,而在電子計算機剛誕生之初並非如此。當時的計算機體積巨大、耗電驚人,當時人們使用穿孔紙帶對其輸入數據與指令:
穿孔紙帶

無疑,這種方式效率低下。故1964年,由美國通用電氣(GE)、國電話電報公司(AT&T)的貝爾實驗室(Bell-Labs)以及麻省理工大學(MIT)的人工智能實驗室組成一個團隊,旨在研製一個運行在大型機上的高效的多任務處理系統,Multics(MULTiplexed Information and Computing System) 就此誕生!

Multics項目是成功的,在達到了最初設定的目標後,到了七十年代,Bell-Labs與GE相繼退出,他們的計算機科學家也將無權再繼續使用Multics。這致使Bell-Labs的一位科學家Ken Thompson開發的一款基於Multics系統的遊戲 Space Travel 無法運行,Ken隨後使用DEC公司的PDP-7主機(當時DEC公司的PDP系列已經到了PDP-11),按照自己對於Multics的理解,重寫了一個能運行自己遊戲的平臺來運行自己的遊戲。

在他向同事們展示Space Travel時,其同事們將目光瞄向了這個底層系統,該系統遂風靡貝爾實驗室。由於該系統設計之初僅僅爲了支持該遊戲的運行,相對於Multics,大家將該系統戲謔地稱爲Unics ,後來更名爲Unix

而Unix此時依然是使用匯編開發的,移植起來較爲繁瑣。Ken好友Dennis Ritchie希望使用高級語言重新開發該系統,遂將當時的B語言進行改進,引入了靜態變量、加入了指針等概念,即成爲了現代C語言的前身。並使用該語言重新了Unix。

1974年,二位公開講述了他們的Unix,將論文刊登於美國計算機通訊雜誌。由於當時的法律,AT&T不能銷售Unix,二人須無償對外提供,Unix迅速風靡各高校以及研究機構。

其中包括加州大學伯克利分校,該校學生Bill Joy成立了CSRG(Computer Systems Research Group),而Ken在休假期間剛好去了該校任教,CSRG成爲了Unix研究的領頭羊4

是時,網絡興起,DARPA將TCP/IP協議棧的研究交給CSRG,CSRG將研究成果整合到了系統中,即BSD(Berkeley System Distribution)。

在這段時間,各地紛紛出現了一些公司,他們包裝發行Unix、編譯器等。如SCO、Microsoft(微軟),Microsoft當年以銷售Basic編譯器爲生,並且也包裝發售Unix,稱爲Xenix。

上世紀八十年代初,IBM Compaq開始生產PC,由於當時Intel的80x86芯片性能很差,而當時的Unix程序員不願將Unix移植到PC兼容機上。加之Bell-Labs若離了AT&T後,迅速將Unix商業化,各個高校與研究機構也無法再免費使用Unix(當時的操作系統很昂貴)。

鑑於此種狀況,又有牛人開始自己研發,美國一位教授開發了CP/M系統,以及另一位默默無聞的程序員開發的QDOS(Quick and Dirty Operating System)。QDOS後來被比爾蓋茨買下,修改後命名爲DOS(Disk Operating System)。並且通過一種新的賣使用許可證的方式銷售該系統的使用權,大獲成功。

另一邊,Apple公司的Jobs在Xerox的PARK實驗室發現了鼠標與圖形操作系統,並將其應用在Apple 2上。其友商Microsoft不久也獲取到了該技術的拷貝,Windows就此誕生!但是內核依然是DOS。

Unix陣營這邊,貝爾實驗室與CSRG的一場長達數年之久的爭論接近尾聲。Bill Joy成立了Sun Microsystem公司,爲世界貢獻了Java語言、Solaris系統、Spark等,後來被Oracle收購。

而當時的DEC公司被COMPAQ收購,其VMS系統團隊加入了微軟,改進Windows,內核更新爲VMS。

上文提到,由於Unix的商業化,衆多高校以及科研機構無法免費使用Unix。麻省理工學院的一位教授Stallman對此大爲不滿,他認爲認爲程序是全人類的,倡導軟件應公開使用,成立GNU(GNU is Not Unix)組織,頒佈了GPL(General Public License)協定5

GNU組織貢獻了衆多優秀的軟件,如EMACS、gcc、vi等。有意思的是,這些軟件只能運行在Unix系統上!

這裏又是一位牛人,荷蘭一大學教授Andrew仿照Unix開發出了Minix(據說只有4000多行代碼),並用它的歐盟各地教學。然而Minix的底層驅動用匯編開發,無法在學生的電腦上使用,一些學生在自己的電腦上開發多中平臺的驅動,但Andrew不同意將這些驅動融合在Minix中。

最後一位壓軸出場的就是LInux之父:Linus Torvalds!1991年8月,還在赫爾辛基大學上學的的Linus寫了一個小系統Linux,並宣佈其遵循GPL協定,任何人可以更改系統。加之其滿足了GUN組織迫切需要一款操作系統的需求。
Linus Torvalds

此後,世界各地的黑客、程序員等紛紛參與其中,不斷完善Linux,Linux就此迅速成長。如今,Linux內核已然相當健壯。

2. 開源協定

軟件的開源(Open Source) 指的是在將源代碼公開,但這並不意味着它沒有版權,爲了開源協定的作用之一,就是保護這類軟件的版權。這裏羅列以下幾個常見的開源協定。

GPL

Gnu general Public License,GNU通用公共許可證,規定了用戶可以自由查看、修改、傳播軟件(及源代碼),其中一些要求如下

  • 若使用了該協定,且欲使用軟件收費,則需要像客戶說明該軟件遵循GPL,客戶可以免費獲得,並且需要說明收費的理由
  • 若軟件用引用了任何遵循GPL的代碼,則該軟件也需要遵循GPL

目前的最新版爲GPL v3.0

LGPL

鑑於GPL軟件的嚴苛,使得其有一種“傳染性”,從某種程度上限制了自由軟件的傳播。LGPL爲Lesser GPL,它較GPL稍顯寬鬆,大致區別在於

  • 可以通過類庫引用的方式使用LGPL代碼,而軟件無需開放源代碼
  • 若修改了LGPL的代碼,則涉及到的代碼以及衍生代碼都需要遵循LGPL

因此,LGPL適合作爲第三方的類庫被使用

目前的最新版本爲LGPL v3.0

BSD License6

BSD協議較以上二者,給了開發者極大的自由,要求爲

  • 使用了遵循BSD協定的軟件後,若發佈的軟件爲源代碼,則在源代碼中必須帶有原來代碼中的BSD協議
  • 如果再發布的只是二進制類庫/軟件,則需要在類庫/軟件的文檔和版權聲明中包含原來代碼中的BSD協議
  • 不能使用原程序作者或組織的名字來對軟件進行宣傳

嚴格來講,BSD許可證是由加州大學伯克利分校(UCB)開發的一類非常簡單且非常自由的計算機軟件許可證。這裏講的是Original BSD license

Apache License

該協定與BSD類似,依然較爲寬鬆

  • 若修改了遵循該協定的代碼,則需要再被修改的文件中進行說明
  • 在衍生出的代碼中需要帶有原來代碼中的協議,商標,專利聲明等,以及原作者規定需要包含的其他說明
  • 若發佈的產品中包含Notice文件,則在Notice文件中需要帶有Apache Licence,同時也可以在Notice中增加自己的許可,但不可以與Apache Licence衝突
  • 需要給代碼的用戶一份Apache Licence

目前的最新版爲Apache License v2.0

下圖說明了各協定間的區別,以及如何選擇7
choosing_opensource_license

3. Linux發行版

Linux與其他應用(如上文提到的gcc、vi等)是使用高級語言開發(Linux源代碼中也混合有低級語言),而程序的運行必須轉換爲二進制格式,對於非專業人員而言,使用難度很大。

再則,Linux內核不提供有生產力的功能,無法直接使用,而獨立的應用程序需要依賴該平臺。如此就有一些組織或商業公司,將Linux與衆多應用程序整合編譯爲二進制程序,使大家可以直接安裝使用。這就是Linux發行版(Distribution)。

Linux有衆多發行版(數百個),其中比較流行的有:

  • RHEL,RedHat Enterprise Linux,紅帽(RedHat)公司發行的商業Linux
  • CentOS,Community ENTerprise OS,社區企業操作系統,兼容RHEL,現已被Redhat收購
  • SUSE,slackware二次發行版,屬於Novell旗下的業務,OpenSUSE是它的二次發行版,有企業版SLES(SUSE Linux Enterprise Server)
  • Ubuntu,debian的二次發行版,擁有華麗的界面,在個人設備上也很流行,其二次發行版Mint也以美觀著稱

三、Linux的獲取

這裏所說的Linux指的是Linux發行版。在國內有衆多發行版鏡像提供的站點,如:

筆者將使用 CentOS 7 進行學習與測試,以阿里云爲例,找到CentOS/7位置,此處將指向當前最新穩定的CentOS 7版本,進入isos/x86_64/


CentOS7鏡像下載

這裏對圖上所列版本做大致說明:

  • DVD版本包含常用的軟件包
  • Everything版本包含了所需的幾乎所有軟件包
  • Live版本可直接運行在移動介質之上
  • Minimal版本只包含了最基礎的軟件,體積較小

建議初學者下載Everything版本,如此,在安裝之後可省去大量的“麻煩”(如所需要的軟件沒有安裝,而自己此時也無從下手)。

另外,LInux Kernel的站點爲:https://www.kernel.org

四、基礎概念說明

作爲學習使用,我們一般將採用將Linux安裝在虛擬機的方式進行。關於如何在虛擬機安裝Linux,這裏不做贅述。以下將通俗介紹一點基本的計算機概念,可能不甚嚴謹,但是幫助初學者理解已然足矣。

1. Shell

之前有提到,計算機有五大結構,人們通過I/O設備與計算機進行交互,那麼通過設備發送的信息是如何傳遞到計算機內部,進而繼續執行的呢?而使用者又是如何知道,何時應該發送何種信息,以及計算機正處於何種狀態呢?

很顯然,我們通過輸出設備獲取信息,而該信息則由專門的一類程序負責,即Shell。Shell意爲“殼”,是指“爲使用者提供操作界面”的軟件,同時也接收用戶命令,然後調用相應的應用程序。是人機交互的聯結者。

Shell大體上分爲兩類:

  • CLI:Command Line Interface,命令行接口
  • GUI:Graphic User Interface,圖形用戶接口

CLI顧名思義,界面只有文字,微軟的DOS系統、Windows中的命令提示符、PowerShell,Linux中的bash,csh,zsh等

GUI之前也曾提到,由施樂研發,與早期計算機使用的命令行界面相比,圖形界面對於用戶來說在視覺上更易於接受,學習成本也較低。如Windows的桌面,Linux的KDE、GNome等。

2.程序與進程

簡單來講,程序即存儲在某介質之上的二進制文件,而進程則是正在運行的佔用硬件資源的活動,或者說是正在運行的程序的實例。上文提到的bash、KDE等,都是如此。

那麼問題來了,計算機內存在斷電後無法保存數據,而計算機在啓動時將運行OS,則需要通過外存將存儲在其中的程序加載到內存,進而由CPU執行。而“將存儲在其中的程序加載”這個指令又是如何執行的呢?

這似乎是一個無解的問題,不過明顯地,該問題已經解決:在計算機內部,有一個專門存儲這段指令的芯片,且數據可持久保存,在機器加電後,將由硬件邏輯將這段代碼加載,進而加載後續的其他進程。

3. 終端

終端Terminal),是一臺計算機或者計算機系統,用來讓用戶輸入數據,及顯示其計算結果的機器。終端有些是全電子的,也有些是機電的。其又名終端機,它與一部獨立的計算機不同。從這個角度而言,計算機可以理解爲主機 + 終端

早期的計算機在需要多人操作時,每個用戶都要有一個顯示器、一個鍵盤。而在現代Linux系統中,以CentOS7爲例,默認將打開6個虛擬終端(Virtual Terminal),按Ctrl+Alt+Fn(F2~F7)切換,也可按Ctrl+Alt+F7啓動圖形終端(需要事先安裝)。

Linux系統支持一下終端類型:

  • 串行終端,設備文件爲:/dev/ttyS#(#爲數字)
  • 物理終端,即控制檯(Console),設備文件爲:/dev/console
  • 虛擬終端,設備文件爲:/dev/tty#(#爲數字)
  • 僞終端,即模擬終端,遠程連接或圖形界面打開的命令接口,設備文件爲:/dev/pts/#(#爲數字)

4. CPU架構

計算機的CPU,即中央處理單元在工作時都需要加載到一些命令,而命令是按照相關的標準,將程序源代碼在被執行前所翻譯出的機器能識別的語言,也叫機器語言,這種翻譯過程就是編譯(Compile),而翻譯時運用的規則叫做指令集(ISA)。最常見的就是RISC(Reduced Instruction Set Computer,精簡指令集計算機),以ARM架構爲代表,和CISC(Complex Instruction Set Computer,複雜指令集計算機),以x86架構爲代表。

而基於某種指令集的具體實現是有多種方式的,這些不同的實現方式基於某一種指令集規範,我們稱之爲Microarchitecture(微架構)。以英特爾的PC平臺爲例,早先奔騰系列產品使用的是P5或P6微架構,到後來第五代酷睿系列使用的Haswell,到如今市場上酷睿使用的Coffee Lake,都是複雜指令集的不同實現。

初次之外,還有以下CPU架構:

  • ARM
    Advanced RISC Machine,高級精簡指令集機器,該CPU以節能與高效著稱。由英國ARM公司設計,這個公司很神奇,他們幾乎不生產CPU,只是向外輸出技術,是全球領先的半導體知識產權 (IP) 提供商。
  • x86,x64

    x86泛指一系列基於Intel 8086且向後兼容的中央處理器指令集架構。Intel在早期以80x86這樣的數字格式來命名處理器,包括Intel 8086、80186、80286、80386以及80486,由於以“86”作爲結尾,因此其架構被稱爲“x86”。

    x86的32位架構一般又被稱作IA-32(Intel Architecture, 32-bit),其64位架構由AMD率先推出,並被稱爲“AMD64”。之後也被Intel採用,被其稱爲“Intel 64”。一般也被稱作“x86-64”、“x64”。8

  • Itanium
    安騰,Intel收購HP的業務,64位架構,與x86,x64不兼容。
  • Alpha
    由DEC公司研發,也叫做Alpha AXP,早起被用戶DEC公司生產的設備中,後來被Compaq收購,後HP收購Compaq,繼續研發Alpha。
  • Power
    由IBM設計,屬於RISC,全稱爲“Performance Optimization With Enhanced RISC”,性能強勁,價格同樣強勁。
  • PowerPC
    Performance Optimization With Enhanced RISC – Performance Computing,簡稱爲PPC。由Apple、IBM、Motorola組成的AIM聯盟所發展出的微處理器架構,早期用於蘋果的CPU。
  • MIPS

    MIPS架構(英語:MIPS architecture,爲Microprocessor without Interlocked Pipeline Stages的縮寫,亦爲Millions of Instructions Per Second的頭字語),是一種採取精簡指令集(RISC)的處理器架構,1981年出現,由MIPS科技公司開發並授權,廣泛被使用在許多電子產品、網絡設備、個人娛樂設備與商業設備上。最早的MIPS架構是32位,最新的版本已經變成64位。9

五、Linux基礎概念

1. Linux哲學思想

Linux系統在設計之時,使用了很有前瞻性的組織機制,如今,這些機制已經被廣泛引用,甚至已經上升到了哲學高度:

  • 由目的單一的小程序組成
    Linux的每一個程序功能都比較單一10,一來可以專注於一件事,提升效率,二來可以減少Bug
  • 組合多個程序完成複雜任務
    我們可以使用管道、重定向以及腳本等組個多個程序完成較爲複雜的功能
  • 一切皆文件
    除了我們用到的數據、程序是以文件的形式展示外,硬件設備、套接字、系統運行參數等都可以以文件形式展示,通過查看或修改文件以達到管理設備、進程間通信以及配置系統運行特性等目的
  • 儘量避免捕捉用戶接口
    Linux系統大量應用在Server領域,在系統運行過程中,系統本身很少與操作者進行交互,繼承此種思路,沒有消息就是最好的消息
  • 配置文件保存爲純文本格式
    配置文件主要用於調整程序的運行特性或方式,使用文本格式保存,可以極大促進其傳播
  • 提供機制,而非策略
    這一點與“授人以漁,而非授人以魚”有着異曲同工個之妙,即提供提供大體規則方向,具體實施方法均由用戶(或開發者)的理解制定,這也是Linux會有如此多的發行版的原因之一!

2. Linux Kernel功能

Kernel,即核心,Linux的Kernel就是Linux操作系統運行的核心。事實上,它並不爲用戶直接提供任何有生產力的功能,而是爲了系統的基本運行提供保障。就如我們心臟的跳動,並我們幫我們完成任何學習與工作任務,但是卻必不可少。

Kernel提供最底層、最通用的能力:

  • 分配系統資源,即將硬件提供的計算能虛擬化爲系統調用,以及對內存的管理
  • 程序管理,程序的啓動、終止、切換、回收等工作
  • 硬件驅動,提供硬件與軟件的基本接口
  • 通用功能,如網絡、文件系統等
  • 安全功能,如SELinux,解密解密算法等

3. 命令提示符

啓動系統,登錄後11會顯示如下信息:

[root@localhost ~]#

這段信息叫做 命令提示符(Prompt),用於提示用戶可在此提示符後鍵入命令。一下對其各部分做以說明:

組件 說明
[ root@localhost ~] # 命令提示符大體分爲兩部分,[]與其中的部分以及後面的提示符
[ root @localhost ~]# 當前登錄用戶,這裏爲root
[root @ localhost ~]# 用於分隔用戶名與主機名,這裏爲@
[root@localhost ~]# 本地主機域名,這裏爲localhost
[root@localhost ~]# 當前的工作目錄(Working Directory)基名(Base Name),這裏爲用戶自己的家目錄,使用“~”表示
[root@localhost ~] # 表示當前用戶的權限,有兩種,管理員爲**#,普通用戶爲$**

關於該提示符的樣式,可在相關文件裏配置,後續會有詳細說明。

4. Linux命令

一般地,用戶發起一個命令,即爲請求內核將某個二進制程序運行爲一個進程,命令本身是一個可執行的程序文件12,可能會調用共享庫文件。

由於需要讓CPU(或內核)理解並執行命令,故命令必須遵循特定格式規範,如Windows系統的.exe文件、.msi文件,Linux系統中的可執行文件格式爲ELF(Executable and Linkable Format)

這裏有一類獨特的程序,即上文提到的Shell程序,它專門負責解析用戶的指令,是介於人類與計算機的接口。解析完成後,啓動相應的程序。如bash,以後的學習中若不做特殊說明,shell程序均指bash。

由於其特殊性,在shell程序內部,內置了一些基本的命令,這類命令稱之爲內建命令(builtin),使用不同的內建命令,執行的即爲shell程序的不同功能(或代碼段)。

而對應地,另一類就是外部命令,一般程序文件名即爲命令名。

可以使用 type命令查看一個命令相關信息,如:

[root@localhost ~]# type cd
cd is a shell builtin
[root@localhost ~]# type vim
vim is /usr/bin/vim

Linux命令的一般格式

Linux命令的一般格式爲:

# COMMAND OPTIONS... ARGUMENTS...

COMMAND:命令

OPTIONS:命令的參數,用於修改命令的執行方式,若有多箇中間須以空格隔開;有短選項與長選項之分:

  • 短選項:-CHAR,多個短選項可以組合使用,如-a -b可寫爲-ab
  • 長選項:-WORD,通常不能組合使用
    另外,有些選項也需要帶有參數,即選項參數,這些參數可能不必帶“-”

ARGUMENTS:命令參數,即命令的作用對象,有的命令可以帶多個參數,各參數之間需要使用使用空格分隔。

六、FHS

0. 文件系統概念

計算機實質上就是處理數據的設備,這些數據在存儲介質中是以文件(File)的形式存在的,而具體該如何保存,以及如何對硬件進行邏輯抽象管理,使其可以保存,就是文件系統的功能之一。

計算機的文件系統是一種存儲和組織計算機數據的方法,它使得對其訪問和查找變得容易,文件系統使用文件和樹形目錄的抽象邏輯概念代替了硬盤和光盤等物理設備使用數據塊的概念,用戶使用文件系統來保存數據不必關心數據實際保存在硬盤(或者光盤)的地址爲多少的數據塊上,只需要記住這個文件的所屬目錄和文件名。在寫入新數據之前,用戶不必關心硬盤上的那個塊地址沒有被使用,硬盤上的存儲空間管理(分配和釋放)功能由文件系統自動完成,用戶只需要記住數據被寫入到了哪個文件中。

廣義角度來講,Linux系統是有底層的Kernel與上層Application組成。其在計算機啓動之前也是以文件的形式存在於外存中,而這些文件保存在外存(以下稱爲磁盤)的何處位置,Linux的衆多發行組織均可以自定義。如此對於用戶的學習和使用而言是極爲不便的,亦不利於其傳播。鑑於此,Linux Foundation(Linux基金會)定義了Linux發行版中,文件所應該遵從的組織方式,即FHS(Filesystem Hierarchy Standard,文件系統層級標準) 13

1. 根文件系統

該規範說明了系統上應該存在哪些目錄,以及不同文件所應該保存的位置,以下爲簡要說明

目錄 說明
/bin 所有用戶可用的基本命令程序文件
/boot 引導加載器必須用到的各靜態文件,如kernel、ramfs(initrd),以及grub(bootloader)等
/dev 設備文件與特殊文件
/etc 系統程序的靜態配置文件
/home 普通的家目錄的集中位置;一般每個普通用戶的家目錄默認爲此目錄下與用戶名同名的子目錄
/lib 爲系統啓動或根文件系統上的應用程序(/bin,/sbin等)提供共享庫,以及爲內核提供內核模塊
/lib64 特定字長系統上的庫文件,如64位系統上爲/lib64
/media 掛載點目錄,通常用來掛載移動設備
/mnt 掛載點目錄,通常掛載額外的臨時文件系統
/opt, /options 附加應用程序的安裝位置,可選
/proc 虛擬文件系統,用於爲內核及進程存儲其相關信息
/root 管理員的家目錄,可選
/run 存放動態的,不持久的應用程序運行數據
/sbin 供管理員使用的工具程序
/srv 系統上運行的服務用到的數據
/sys sysfs虛擬文件系統提供了一種比proc更爲理想的訪問內核數據的途徑;其主要作用在於爲管理Linux設備提供一種統一模型的的接口
/tmp 臨時文件
/usr 全局共享的只讀數據路徑
/var 頻繁發生變化的文件
/misc 備用目錄,可選
/selinux SELinux(Security Enhanced Linux)相關的安全策略等信息的存儲位置
[root@localhost ~]# ls /
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

2. /usr目錄層級

usr意爲universal shared read-only file,全局共享只讀文件,即該目錄可以在所有遵循FHS的主機間共享(只讀)

目錄 說明
/usr/include C程序頭文件
/usr/bin 普通用戶命令
/usr/sbin 供管理員使用的命令
/usr/lib 庫文件
/usr/lib<qual> 特定字長系統上的庫文件,如64位系統上爲/usr/lib64
/usr/share 命令手冊也和自帶文檔等架構特有的文件的存儲位置,例如doc, man等
/usr/X11R6 X-Window程序的安裝位置(可選)
/usr/src 程序源碼文件的存儲位置
/usr/local 第三方軟件的安裝路徑,也是一個獨立層級
/usr/games 遊戲或教育程序

/usr/local:local目錄層級

該目錄也是一個獨立的層級,其中有bin,sbin等目錄,如下內容引用自 https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLOCALLOCALHIERARCHY

The /usr/local hierarchy is for use by the system administrator when installing software locally. It needs to be safe from being overwritten when the system software is updated. It may be used for programs and data that are shareable amongst a group of hosts, but not found in /usr.
Locally installed software must be placed within /usr/local rather than /usr unless it is being installed to replace or upgrade software in /usr.

Directory Description
bin Local binaries
etc Host-specific system configuration for local binaries
games Local game binaries
include Local C header files
lib Local libraries
man Local online manuals
sbin Local system binaries
share Local architecture-independent hierarchy
src Local source code

3. /var目錄層級

/var contains variable data files. This includes spool directories and files, administrative and logging data, and transient and temporary files.
Some portions of /var are not shareable between different systems. For instance, /var/log, /var/lock, and /var/run. Other portions may be shared, notably /var/mail, /var/cache/man, /var/cache/fonts, and /var/spool/news.
/var is specified here in order to make it possible to mount /usr read-only. Everything that once went into /usr that is written to during system operation (as opposed to installation and software maintenance) must be in /var.
If /var cannot be made a separate partition, it is often preferable to move /var out of the root partition and into the /usr partition. (This is sometimes done to reduce the size of the root partition or when space runs low in the root partition.) However, /var must not be linked to /usr because this makes separation of /usr and /var more difficult and is likely to create a naming conflict. Instead, link /var to /usr/var.
Applications must generally not add directories to the top level of /var. Such directories should only be added if they have some system-wide implication, and in consultation with the FHS mailing list.14

目錄 說明
/var/log 日誌目錄及文件
/var/lock 鎖文件
/var/run 運行中的進程相關的數據,通常用於存放進程的PID文件
/var/cache 應用程序緩存數據目錄
/var/lib 應用程序狀態信息數據
/var/local 專用於爲/usr/local下的應用程序存儲可變數據
/var/opt 專用於爲/opt下的應用程序存儲可變數據
/var/spool 應用程序數據池
/vat/tmp 保存系統兩次重啓之間產生的臨時數據

4. /sys目錄內容

/sys 下的子目錄 所包含的內容
/sys/devices 這是內核對系統中所有設備的分層次表達模型,也是 /sys 文件系統管理設備的最重要的目錄結構,下文會對它的內部結構作進一步分析;
/sys/dev 這個目錄下維護一個按字符設備和塊設備的主次號碼(major:minor)鏈接到真實的設備(/sys/devices下)的符號鏈接文件,它是在內核 2.6.26 首次引入;
/sys/bus 這是內核設備按總線類型分層放置的目錄結構, devices 中的所有設備都是連接於某種總線之下,在這裏的每一種具體總線之下可以找到每一個具體設備的符號鏈接,它也是構成 Linux 統一設備模型的一部分;
/sys/class 這是按照設備功能分類的設備模型,如系統所有輸入設備都會出現在 /sys/class/input 之下,而不論它們是以何種總線連接到系統。它也是構成 Linux 統一設備模型的一部分;
/sys/block 這裏是系統中當前所有的塊設備所在,按照功能來說放置在 /sys/class 之下會更合適,但只是由於歷史遺留因素而一直存在於 /sys/block, 但從 2.6.22 開始就已標記爲過時,只有在打開了 CONFIG_SYSFS_DEPRECATED 配置下編譯纔會有這個目錄的存在,並且在 2.6.26 內核中已正式移到 /sys/class/block, 舊的接口 /sys/block 爲了向後兼容保留存在,但其中的內容已經變爲指向它們在 /sys/devices/ 中真實設備的符號鏈接文件;
/sys/firmware 這裏是系統加載固件機制的對用戶空間的接口,關於固件有專用於固件加載的一套API,在附錄 LDD3 一書中有關於內核支持固件加載機制的更詳細的介紹;
/sys/fs 這裏按照設計是用於描述系統中所有文件系統,包括文件系統本身和按文件系統分類存放的已掛載點,但目前只有 fuse,gfs2 等少數文件系統支持 sysfs 接口,一些傳統的虛擬文件系統(VFS)層次控制參數仍然在 sysctl (/proc/sys/fs) 接口中中;
/sys/kernel 這裏是內核所有可調整參數的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等幾項較新的設計在使用它,其它內核可調整參數仍然位於 sysctl (/proc/sys/kernel) 接口中 ;
/sys/module 這裏有系統中所有模塊的信息,不論這些模塊是以內聯(inlined)方式編譯到內核映像文件(vmlinuz)中還是編譯爲外部模塊(ko文件),都可能會出現在 /sys/module 中:
● 編譯爲外部模塊(ko文件)在加載後會出現對應的 /sys/module/<module_name>/, 並且在這個目錄下會出現一些屬性文件和屬性目錄來表示此外部模塊的一些信息,如版本號、加載狀態、所提供的驅動程序等;
● 編譯爲內聯方式的模塊則只在當它有非0屬性的模塊參數時會出現對應的 /sys/module/<module_name>, 這些模塊的可用參數會出現在 /sys/modules//parameters/<param_name> 中,
●● 如 /sys/module/printk/parameters/time 這個可讀寫參數控制着內聯模塊 printk 在打印內核消息時是否加上時間前綴;
●● 所有內聯模塊的參數也可以由 “<module_name>.<param_name>=” 的形式寫在內核啓動參數上,如啓動內核時加上參數 “printk.time=1” 與 向 “/sys/module/printk/parameters/time” 寫入1的效果相同;
● 沒有非0屬性參數的內聯模塊不會出現於此。
/sys/power 這裏是系統中電源選項,這個目錄下有幾個屬性文件可以用於控制整個機器的電源狀態,如可以向其中寫入控制命令讓機器關機、重啓等。
/sys/slab (對應 2.6.23 內核,在 2.6.24 以後移至 /sys/kernel/slab) 從2.6.23 開始可以選擇 SLAB 內存分配器的實現,並且新的 SLUB(Unqueued Slab Allocator)被設置爲缺省值;如果編譯了此選項,在 /sys 下就會出現 /sys/slab ,裏面有每一個 kmem_cache 結構體的可調整參數。對應於舊的 SLAB 內存分配器下的 /proc/slabinfo 動態調整接口,新式的 /sys/kernel/slab/<slab_name> 接口中的各項信息和可調整項顯得更爲清晰。15

5. 其他說明

設備文件

  • 塊設備(b)
  • 字符設備(c)
  • 設備號:對設備文件使用ls -l查看時,顯示文件大小的位置顯示爲2個數字,即主設備號(major number)與次設備號(minor number)
    • 主設備號,用於標識設備類型,進而確定要加載的驅動程序
    • 次設備號,用於標識同一類型中的不同的設備;

如:

[root@localhost ~]# ls -l /dev
total 0
crw-rw----. 1 root video    10, 175 Dec 28 22:21 agpgart
crw-------. 1 root root     10, 235 Dec 28 22:21 autofs
drwxr-xr-x. 2 root root         180 Dec 28 22:21 block
drwxr-xr-x. 2 root root          80 Dec 28 22:21 bsg
crw-------. 1 root root     10, 234 Dec 28 22:21 btrfs-control
drwxr-xr-x. 3 root root          60 Dec 28 22:21 bus
lrwxrwxrwx. 1 root root           3 Dec 28 22:21 cdrom -> sr0
drwxr-xr-x. 2 root root         100 Dec 28 22:21 centos
drwxr-xr-x. 2 root root        3060 Dec 28 22:21 char
crw-------. 1 root root      5,   1 Dec 28 22:21 console
lrwxrwxrwx. 1 root root          11 Dec 28 22:21 core -> /proc/kcore
drwxr-xr-x. 6 root root         140 Dec 28 22:21 cpu

/etc中常見目錄

  • /etc/opt:/opt下程序的配置文件
  • /etc/sysconfig: 系統級別應用配置
  • /etc/init.d: 系統服務腳本
  • /etc/X11:X協議相關配置文件
  • /etc/sgml:SGML相關配置文件
  • /etc/xml:XML相關配置文件

庫文件

  • 在/lib與/lib64中保存有共享庫文件
  • 靜態庫:.a文件,直接鏈接到程序的地址空間中,作爲程序的一部分額運行,便於程序單獨管理
  • 動態庫:.so(shared object)文件,即使有多個程序要使用,在內存中也只有一份
  • libc.so.*:動態鏈接的C庫
  • ld*:運行時鏈接器/加載器
  • modules:內核模塊文件存儲目錄

Linux上的應用程序的組成部分總結

  • 二進制程序: /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
  • 庫文件:/lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, usr/local/lib64
  • 配置文件:/etc, /etc/DIRECTORY, /usr/local/etc
  • 幫助文件:/usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc

  1. 此處指的是Linux Kernel ↩︎

  2. 引用自 https://en.wikipedia.org/wiki/Von_Neumann_architecture ↩︎ ↩︎

  3. 詳見 https://en.wikipedia.org/wiki/Binary_number ↩︎

  4. 據說CSRG後來由美國DARPA資助,專門致力於改進AT&TUnix操作系統。 ↩︎

  5. 詳見下文。 ↩︎

  6. 這個協定其實很有意思,可以看看這裏: http://www.linfo.org/bsdlicense.html#disclaimer ↩︎

  7. 圖片來源 https://leohacker.files.wordpress.com/2011/05/choosing_opensource_license.png ↩︎

  8. 詳見 https://en.wikipedia.org/wiki/X86 ↩︎

  9. 引用自 https://zh.wikipedia.org/wiki/MIPS架構 ↩︎

  10. 那些提供複雜服務解決方案的程序除外 ↩︎

  11. 這裏使用root用戶登錄,僅作爲測試學習,在生產環境中,不應該使用該用戶登錄系統! ↩︎

  12. 也有可能出現多個命令對應一個程序文件的情況,如bash的內建(builtin) 命令。 ↩︎

  13. 目前的最新版爲FHS3.0,詳見 https://refspecs.linuxfoundation.org/fhs.shtml ↩︎

  14. 引用自 https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#THEVARHIERARCHY ↩︎

  15. 表格內容引用自 https://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/ ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章