Linux 操做系統!開篇!!!

此篇文章主要會帶你介紹 Linux 操做系統,包括 Linux 自己、Linux 如何使用、以及系統調用和 Linux 是如何工做的。程序員

Linux 簡介

UNIX 是一個交互式系統,用於同時處理多進程和多用戶同時在線。爲何要說 UNIX,那是由於 Linux 是由 UNIX 發展而來的,UNIX 是由程序員設計,它的主要服務對象也是程序員。Linux 繼承了 UNIX 的設計目標。從智能手機到汽車,超級計算機和家用電器,從家用臺式機到企業服務器,Linux 操做系統無處不在。shell

大多數程序員都喜歡讓系統儘可能簡單,優雅並具備一致性。舉個例子,從最底層的角度來說,一個文件應該只是一個字節集合。爲了實現順序存取、隨機存取、按鍵存取、遠程存取只能是妨礙你的工做。相同的,若是命令瀏覽器

ls A*
複製代碼

意味着只列出以 A 爲開頭的全部文件,那麼命令緩存

rm A*
複製代碼

應該會移除全部以 A 爲開頭的文件而不是隻刪除文件名是 A* 的文件。這個特性也是最小吃驚原則(principle of least surprise)bash

最小吃驚原則一半經常使用於用戶界面和軟件設計。它的原型是:該功能或者特徵應該符合用戶的預期,不該該使用戶感到驚訝和震驚。服務器

一些有經驗的程序員一般但願系統具備較強的功能性和靈活性。設計 Linux 的一個基本目標是每一個應用程序只作一件事情並把他作好。因此編譯器只負責編譯的工做,編譯器不會產生列表,由於有其餘應用比編譯器作的更好。網絡

不少人都不喜歡冗餘,爲何在 cp 就能描述清楚你想幹何時還使用 copy?這徹底是在浪費寶貴的 hacking time。爲了從文件中提取全部包含字符串 ard 的行,Linux 程序員應該輸入併發

grep ard f
複製代碼

Linux 接口

Linux 系統是一種金字塔模型的系統,以下所示socket

應用程序發起系統調用把參數放在寄存器中(有時候放在棧中),併發出 trap 系統陷入指令切換用戶態至內核態。由於不能直接在 C 中編寫 trap 指令,所以 C 提供了一個庫,庫中的函數對應着系統調用。有些函數是使用匯編編寫的,可是可以從 C 中調用。每一個函數首先把參數放在合適的位置而後執行系統調用指令。所以若是你想要執行 read 系統調用的話,C 程序會調用 read 函數庫來執行。這裏順便提一下,是由 POSIX 指定的庫接口而不是系統調用接口。也就是說,POSIX 會告訴一個標準系統應該提供哪些庫過程,它們的參數是什麼,它們必須作什麼以及它們必須返回什麼結果。編輯器

除了操做系統和系統調用庫外,Linux 操做系統還要提供一些標準程序,好比文本編輯器、編譯器、文件操做工具等。直接和用戶打交道的是上面這些應用程序。所以咱們能夠說 Linux 具備三種不一樣的接口:系統調用接口、庫函數接口和應用程序接口

Linux 中的 GUI(Graphical User Interface) 和 UNIX 中的很是類似,這種 GUI 建立一個桌面環境,包括窗口、目標和文件夾、工具欄和文件拖拽功能。一個完整的 GUI 還包括窗口管理器以及各類應用程序。

Linux 上的 GUI 由 X 窗口支持,主要組成部分是 X 服務器、控制鍵盤、鼠標、顯示器等。當在 Linux 上使用圖形界面時,用戶能夠經過鼠標點擊運行程序或者打開文件,經過拖拽將文件進行復制等。

Linux 組成部分

事實上,Linux 操做系統能夠由下面這幾部分構成

  • 引導程序(Bootloader):引導程序是管理計算機啓動過程的軟件,對於大多數用戶而言,只是彈出一個屏幕,但其實內部操做系統作了不少事情
  • 內核(Kernel):內核是操做系統的核心,負責管理 CPU、內存和外圍設備等。
  • 初始化系統(Init System):這是一個引導用戶空間並負責控制守護程序的子系統。一旦從引導加載程序移交了初始引導,它就是用於管理引導過程的初始化系統。
  • 後臺進程(Daemon):後臺進程顧名思義就是在後臺運行的程序,好比打印、聲音、調度等,它們能夠在引導過程當中啓動,也能夠在登陸桌面後啓動
  • 圖形服務器(Graphical server):這是在監視器上顯示圖形的子系統。一般將其稱爲 X 服務器或 X。
  • 桌面環境(Desktop environment):這是用戶與之實際交互的部分,有不少桌面環境可供選擇,每一個桌面環境都包含內置應用程序,好比文件管理器、Web 瀏覽器、遊戲等
  • 應用程序(Applications):桌面環境不提供完整的應用程序,就像 Windows 和 macOS 同樣,Linux 提供了成千上萬個能夠輕鬆找到並安裝的高質量軟件。

Shell

儘管 Linux 應用程序提供了 GUI ,可是大部分程序員仍偏好於使用命令行(command-line interface),稱爲shell。用戶一般在 GUI 中啓動一個 shell 窗口而後就在 shell 窗口下進行工做。

shell 命令行使用速度快、功能更強大、並且易於擴展、而且不會帶來肢體重複性勞損(RSI)

下面會介紹一些最簡單的 bash shell。當 shell 啓動時,它首先進行初始化,在屏幕上輸出一個 提示符(prompt),一般是一個百分號或者美圓符號,等待用戶輸入

等用戶輸入一個命令後,shell 提取其中的第一個詞,這裏的詞指的是被空格或製表符分隔開的一連串字符。假定這個詞是將要運行程序的程序名,那麼就會搜索這個程序,若是找到了這個程序就會運行它。而後 shell 會將本身掛起直到程序運行完畢,以後再嘗試讀入下一條指令。shell 也是一個普通的用戶程序。它的主要功能就是讀取用戶的輸入和顯示計算的輸出。shell 命令中能夠包含參數,它們做爲字符串傳遞給所調用的程序。好比

cp src dest
複製代碼

會調用 cp 應用程序幷包含兩個參數 srcdest。這個程序會解釋第一個參數是一個已經存在的文件名,而後建立一個該文件的副本,名稱爲 dest。

並非全部的參數都是文件名,好比下面

head -20 file
複製代碼

第一個參數 -20,會告訴 head 應用程序打印文件的前 20 行,而不是默認的 10 行。控制命令操做或者指定可選值的參數稱爲標誌(flag),按照慣例標誌應該使用 - 來表示。這個符號是必要的,好比

head 20 file
複製代碼

是一個徹底合法的命令,它會告訴 head 程序輸出文件名爲 20 的文件的前 10 行,而後輸出文件名爲 file 文件的前 10 行。Linux 操做系統能夠接受一個或多個參數。

爲了更容易的指定多個文件名,shell 支持 魔法字符(magic character),也被稱爲通配符(wild cards)。好比,* 能夠匹配一個或者多個可能的字符串

ls *.c
複製代碼

告訴 ls 列舉出全部文件名以 .c 結束的文件。若是同時存在多個文件,則會在後面進行並列。

另外一個通配符是問號,負責匹配任意一個字符。一組在中括號中的字符能夠表示其中任意一個,所以

ls [abc]*
複製代碼

會列舉出全部以 ab 或者 c 開頭的文件。

shell 應用程序不必定經過終端進行輸入和輸出。shell 啓動時,就會獲取 標準輸入、標準輸出、標準錯誤文件進行訪問的能力。

標準輸出是從鍵盤輸入的,標準輸出或者標準錯誤是輸出到顯示器的。許多 Linux 程序默認是從標準輸入進行輸入並從標準輸出進行輸出。好比

sort	
複製代碼

會調用 sort 程序,會從終端讀取數據(直到用戶輸入 ctrl-d 結束),根據字母順序進行排序,而後將結果輸出到屏幕上。

一般還能夠重定向標準輸入和標準輸出,重定向標準輸入使用 < 後面跟文件名。標準輸出能夠經過一個大於號 > 進行重定向。容許一個命令中重定向標準輸入和輸出。例如命令

sort <in >out
複製代碼

會使 sort 從文件 in 中獲得輸入,並把結果輸出到 out 文件中。因爲標準錯誤沒有重定向,因此錯誤信息會直接打印到屏幕上。從標準輸入讀入,對其進行處理並將其寫入到標準輸出的程序稱爲 過濾器

考慮下面由三個分開的命令組成的指令

sort <in >temp;head -30 <temp;rm temp
複製代碼

首先會調用 sort 應用程序,從標準輸入 in 中進行讀取,並經過標準輸出到 temp。當程序運行完畢後,shell 會運行 head ,告訴它打印前 30 行,並在標準輸出(默認爲終端)上打印。最後,temp 臨時文件被刪除。輕輕的,你走了,你揮一揮衣袖,不帶走一片雲彩

命令行中的第一個程序一般會產生輸出,在上面的例子中,產生的輸出都不 temp 文件接收。然而,Linux 還提供了一個簡單的命令來作這件事,例以下面

sort <in | head -30
複製代碼

上面 | 稱爲豎線符號,它的意思是從 sort 應用程序產生的排序輸出會直接做爲輸入顯示,無需建立、使用和移除臨時文件。由管道符號鏈接的命令集合稱爲管道(pipeline)。例如以下

grep cxuan *.c | sort | head -30 | tail -5 >f00
複製代碼

對任意以 .t 結尾的文件中包含 cxuan 的行被寫到標準輸出中,而後進行排序。這些內容中的前 30 行被 head 出來並傳給 tail ,它又將最後 5 行傳遞給 foo。這個例子提供了一個管道將多個命令鏈接起來。

能夠把一系列 shell 命令放在一個文件中,而後將此文件做爲輸入來運行。shell 會按照順序對他們進行處理,就像在鍵盤上鍵入命令同樣。包含 shell 命令的文件被稱爲 shell 腳本(shell scripts)

推薦一個 shell 命令的學習網站:www.shellscript.sh/

shell 腳本其實也是一段程序,shell 腳本中能夠對變量進行賦值,也包含循環控制語句好比 if、for、while 等,shell 的設計目標是讓其看起來和 C 類似(There is no doubt that C is father)。因爲 shell 也是一個用戶程序,因此用戶能夠選擇不一樣的 shell。

Linux 應用程序

Linux 的命令行也就是 shell,它由大量標準應用程序組成。這些應用程序主要有下面六種

  • 文件和目錄操做命令
  • 過濾器
  • 文本程序
  • 系統管理
  • 程序開發工具,例如編輯器和編譯器
  • 其餘

除了這些標準應用程序外,還有其餘應用程序好比 Web 瀏覽器、多媒體播放器、圖片瀏覽器、辦公軟件和遊戲程序等

咱們在上面的例子中已經見過了幾個 Linux 的應用程序,好比 sort、cp、ls、head,下面咱們再來認識一下其餘 Linux 的應用程序。

咱們先從幾個例子開始講起,好比

cp a b
複製代碼

是將 a 複製一個副本爲 b ,而

mv a b
複製代碼

是將 a 移動到 b ,可是刪除原文件。

上面這兩個命令有一些區別,cp 是將文件進行復制,複製完成後會有兩個文件 a 和 b;而 mv 至關因而文件的移動,移動完成後就再也不有 a 文件。cat 命令能夠把多個文件內容進行鏈接。使用 rm 能夠刪除文件;使用 chmod 能夠容許全部者改變訪問權限;文件目錄的的建立和刪除可使用 mkdirrmdir 命令;使用 ls 能夠查看目錄文件,ls 能夠顯示不少屬性,好比大小、用戶、建立日期等;sort 決定文件的顯示順序

Linux 應用程序還包括過濾器 grep,grep 從標準輸入或者一個或多個輸入文件中提取特定模式的行;sort 將輸入進行排序並輸出到標準輸出;head 提取輸入的前幾行;tail 提取輸入的後面幾行;除此以外的過濾器還有 cutpaste,容許對文本行的剪切和複製;od 將輸入轉換爲 ASCII ;tr 實現字符大小寫轉換;pr 爲格式化打印輸出等。

程序編譯工具使用 gcc

make 命令用於自動編譯,這是一個很強大的命令,它用於維護一個大的程序,每每這類程序的源碼由許多文件構成。典型的,有一些是 header files 頭文件,源文件一般使用 include 指令包含這些文件,make 的做用就是跟蹤哪些文件屬於頭文件,而後安排自動編譯的過程。

下面列出了 POSIX 的標準應用程序

程序 應用
ls 列出目錄
cp 複製文件
head 顯示文件的前幾行
make 編譯文件生成二進制文件
cd 切換目錄
mkdir 建立目錄
chmod 修改文件訪問權限
ps 列出文件進程
pr 格式化打印
rm 刪除一個文件
rmdir 刪除文件目錄
tail 提取文件最後幾行
tr 字符集轉換
grep 分組
cat 將多個文件連續標準輸出
od 以八進制顯示文件
cut 從文件中剪切
paste 從文件中粘貼

Linux 內核結構

在上面咱們看到了 Linux 的總體結構,下面咱們從總體的角度來看一下 Linux 的內核結構

內核直接坐落在硬件上,內核的主要做用就是 I/O 交互、內存管理和控制 CPU 訪問。上圖中還包括了 中斷調度器,中斷是與設備交互的主要方式。中斷出現時調度器就會發揮做用。這裏的低級代碼中止正在運行的進程,將其狀態保存在內核進程結構中,並啓動驅動程序。進程調度也會發生在內核完成一些操做而且啓動用戶進程的時候。圖中的調度器是 dispatcher。

注意這裏的調度器是 dispatcher 而不是 scheduler,這二者是有區別的

scheduler 和 dispatcher 都是和進程調度相關的概念,不一樣的是 scheduler 會從幾個進程中隨意選取一個進程;而 dispatcher 會給 scheduler 選擇的進程分配 CPU。

而後,咱們把內核系統分爲三部分。

  • I/O 部分負責與設備進行交互以及執行網絡和存儲 I/O 操做的全部內核部分。

從圖中能夠看出 I/O 層次的關係,最高層是一個虛擬文件系統,也就是說無論文件是來自內存仍是磁盤中,都是通過虛擬文件系統中的。從底層看,全部的驅動都是字符驅動或者塊設備驅動。兩者的主要區別就是是否容許隨機訪問。網絡驅動設備並非一種獨立的驅動設備,它其實是一種字符設備,不過網絡設備的處理方式和字符設備不一樣。

上面的設備驅動程序中,每一個設備類型的內核代碼都不一樣。字符設備有兩種使用方式,有一鍵式的好比 vi 或者 emacs ,須要每個鍵盤輸入。其餘的好比 shell ,是須要輸入一行按回車鍵將字符串發送給程序進行編輯。

網絡軟件一般是模塊化的,由不一樣的設備和協議來支持。大多數 Linux 系統在內核中包含一個完整的硬件路由器的功能,可是這個不能和外部路由器相比,路由器上面是協議棧,包括 TCP/IP 協議,協議棧上面是 socket 接口,socket 負責與外部進行通訊,充當了門的做用。

磁盤驅動上面是 I/O 調度器,它負責排序和分配磁盤讀寫操做,以儘量減小磁頭的無用移動。

  • I/O 右邊的是內存部件,程序被裝載進內存,由 CPU 執行,這裏會涉及到虛擬內存的部件,頁面的換入和換出是如何進行的,壞頁面的替換和常用的頁面會進行緩存。

  • 進程模塊負責進程的建立和終止、進程的調度、Linux 把進程和線程看做是可運行的實體,並使用統一的調度策略來進行調度。

在內核最頂層的是系統調用接口,全部的系統調用都是通過這裏,系統調用會觸發一個 trap,將系統從用戶態轉換爲內核態,而後將控制權移交給上面的內核部件。

相關文章
相關標籤/搜索