走進 Linux shell (一)

1. GNU/Linux shell


GNU/Linux shell是一種特殊的交互式工具。它爲用戶提供了啓動程序,管理文件系統的文件,以及管理運行在 Linux 系統上的進程的途徑。shell 的核心
是命令行提示符。命令行提示符是 shell 負責交互的部分,它允許輸入文本命令,然後解釋命令,並在內核中執行。

shell 包含了一組內部命令,用這些命令可以完成諸如複製文件,移動文件,重命名文件,顯示和終止系統中正在運行的程序等操作。shell 也允許在命令行
提示符中輸入程序的名稱,它會將程序名傳遞給內核以啓動它。

也可以將多個 shell 命令放入文件中作爲程序執行,這些文件被稱作 shell 腳本。在命令行上執行的任何命令都可以放進一個 shell 腳本中作爲一組命令
的一部分執行,這爲創建那種需要把幾個命令放在一起的來工作的工具提供了便利。

在 Linux 系統中,通常有好幾種 Linux shell 可用。不同的 shell 有不同的特性,有些更利於創建腳本,有些則更利於管理進程。所有 Linux 發行版默認
的 shell 都是 bash shell. bash shell 由 GNU 項目開發,被當做標準的 Unix shell —— Bourne shell(以創建者的名字命名)的替代品。

除了 bash shell, 還有其它幾種常見的 shell, 下表列出 Linux 中常見的幾種 shell

        Linux shell
        +-------+---------------------------------------------------------------------------------------------------+
        | shell    |    描 述                                                                                            |
        +-------+---------------------------------------------------------------------------------------------------+
        | ash    | 一種運行在內存受限環境中簡單的輕量級shell,但與bash shell完全兼容                                    |
        +-------+---------------------------------------------------------------------------------------------------+
        | korn    | 一種與Bourne shell兼容的編程shell,但支持如關聯數組和浮點運算等一些高級的編程特性                    |
        +-------+---------------------------------------------------------------------------------------------------+
        | tcsh    | 一種將C語言中的一些元素引入到shell腳本中的shell                                                    |
        +-------+---------------------------------------------------------------------------------------------------+
        | zsh    | 一種結合了bash、tcsh和korn的特性,同時提供高級編程特性、共享歷史文件和主題化提示符的高級 shell    |
        +-------+---------------------------------------------------------------------------------------------------+

 

2. 進入命令行
-----------------------------------------------------------------------------------------------------------------------------------------
由shell所提供的文本命令行界面(command line interface, CLI), 只能接受文本輸入,也只能顯示出文本和基本的圖形輸出。

 

2.1 控制檯終端
-----------------------------------------------------------------------------------------------------------------------------------------
進入 CLI 的一種方法時讓 Linux 系統退出圖形化桌面模式,進入文本模式。這樣在顯示器上就只有一個簡單的 shell CLI, 跟圖形化桌面出現以前一樣,這
種模式成爲 Linux 控制檯,它仿真了早期的硬接線控制檯終端,而且是一種同 Linux 系統交互的直接接口。

Linux 系統啓動後,它會自動創建一些虛擬控制檯。虛擬控制檯是運行在 Linux 系統內存中的終端會話。不需要在計算機上連接多個啞終端,大多數 Linux
發行版都會啓動 5~6 個(可能更多)的虛擬控制檯,在計算機鍵盤上就可以訪問它們,按鍵 Ctrl + Alt + F1~F7。

 

2.2 圖形化終端
-----------------------------------------------------------------------------------------------------------------------------------------
除了虛擬化終端控制檯,還可以使用Linux圖形化桌面環境中的終端仿真包。終端仿真包會在一個桌面圖形化窗口中模擬控制檯終端的使用。相較於虛擬化
控制檯終端,圖形化桌面環境提供了更多訪問 CLI 的方式。在圖形化環境下,有大量可用的圖形化終端仿真器。每個軟件包都有各自獨特的特性和選項。其
中常用的軟件包有:GNOME Terminal, Konsole Terminal 和 xterm。


    ■ 使用GNOME Terminal 仿真器
    -------------------------------------------------------------------------------------------------------------------------------------
    GNOME Terminal 是 GNOME 桌面環境的默認終端仿真器。很多發行版,如 RHEL、Fedora 和 CentOS,默認採用的都是 GNOME 桌面環境,因此 GNOME
    Terminal 自然也就是默認配備。不過其他一些桌面環境,比如 Ubuntu Unity,也採用 GNOME Terminal 作爲默認的終端仿真軟件包。

    在GNOME桌面環境中,找到左上角的菜單,點擊 Applications,從下拉菜單中選擇System Tools,點擊 Terminal。寫成簡寫法的話,這一系列操作就像
    這樣:Applications > System Tools > Terminal。

    在 Unity 桌面環境中,Dash > Search,然後輸入 Terminal。GNOME 終端會作爲一個名爲 Terminal 的應用程序顯示在Dash區域。點擊對應的圖標就可
    以打開 GNOME 終端仿真器。


    ■ 使用Konsole Terminal 仿真器
    -------------------------------------------------------------------------------------------------------------------------------------
    Konsole Terminal 是 KDE 桌面環境的默認終端仿真器,必須通過菜單才能訪問。找到屏幕左下角名爲 Kickoff Application Launcher 的圖標,然後
    依次點擊 Applications > System > Terminal (Konsole)。


    ■ 使用xterm 終端仿真器
    -------------------------------------------------------------------------------------------------------------------------------------
    最古老也是最基礎的終端仿真軟件包是xterm。xterm軟件包在X Window出現之前就有了,通常默認包含在發行版中。儘管xterm是功能完善的仿真軟件包,
    但是它並不需要太多的資源(如內存)來運行。正因爲如此,在專門爲老舊硬件設計的 Linux 發行版中,xterm非 常流行。有些圖形化桌面環境就用它
    作爲默認終端仿真器軟件包。

    在 Ubuntu 的 Unity桌面中,xterm 是默認安裝的。可以通過 Dash > Search,然後輸入 xterm 進行訪問。xterm 會作爲一個名爲 XTerm 的應用出現在
    Dash 區域。點擊對應的圖標就可以打開 xterm 終端仿真器。

    GNOME 和 KDE 桌面環境中並沒有默認安裝 xterm。得先安裝它。安裝完成之後,必須從另一個終端仿真器中啓動xterm。打開一個終端仿真器進入CLI,
    輸入 xterm 並按回車鍵。

 

    
3. 基本的 bash shell 命令
-----------------------------------------------------------------------------------------------------------------------------------------
GNU bash shell 能提供對 Linux 系統的交互式訪問,它是作爲普通程序運行的,通常是在用戶登錄終端時啓動。登錄時系統啓動的 shell 依賴於用戶賬號
的配置。

/etc/passwd 文件包含了所有系統用戶賬戶列表以及每個用戶的基本配置信息,其中包括賬戶登錄時所使用的 shell:

    devalone:x:1000:1000:MichaelY.:/home/devalone:/bin/bash

此文件的每一個條目爲一行,有七個字段,字段之間用冒號分隔,其中最後一個字段指定了用戶使用的 shell 程序。

儘管 bash shell 會在登錄時自動啓動,但是否會出現 shell 命令行界面則依賴於所使用的登錄方式。如果採用虛擬控制檯登錄, CLI 提示符會自動出現,
可以輸入 shell 命令,但如果通過圖形化桌面環境登錄 Linux 系統,就需要啓動一個圖形化終端仿真器來訪問 shell CLI 提示符。

 

3.1 遍歷目錄
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 將文件存儲在單個目錄結構中,這個目錄被稱爲虛擬目錄 (virtual directory)。虛擬目錄將安裝在 PC 上的所有存儲設備的文件路徑納入單個目錄
結構中。Linux 虛擬目錄結構只包含一個稱爲根 (root) 目錄的基礎目錄。根目錄下的目錄和文件會按照訪問它們的目錄路徑一一列出。

在 Linux 文件系統上,可以使用切換目錄命令 cd 將 shell 會話切換到另一目錄。

格式:
    cd destination
    
cd 命令可接受單個參數 destination, 用以指定想切換到的目錄名。如果沒有爲 cd 命令指定目標路徑,它將切換到用戶主目錄。

destination 參數可以用兩種方式表示:一種是使用絕對文件路徑,另一種是使用相對文件路徑。


    ● 絕對文件路徑
    -------------------------------------------------------------------------------------------------------------------------------------
    用戶可在虛擬目錄中採用絕對文件路徑引用目錄名。絕對文件路徑定義了在虛擬目錄結構中該目錄的確切位置,以虛擬目錄的根目錄開始,相當於目錄的
    全名。絕對文件路徑總是以正斜線(/)作爲起始,指明虛擬文件系統的根目錄。因此,如果要指向 usr 目錄所包含的 bin 目錄下的用戶二進制文件,可
    以使用如下絕對文件路徑:

        /usr/bin
        
    使用絕對文件路徑可以清晰表明用戶想切換到的確切位置。要用絕對文件路徑來切換到文件系統中的某個特定位置,只需在 cd 命令後指定全路徑名:
    
        [devalone@devalone ~]$ cd /usr/bin
        [devalone@devalone bin]$
        
    波浪號(~) 表明 shell 會話位於用戶的主目錄中。
    
    pwd 命令可以顯示出 shell 會話的當前目錄,這個目錄被稱爲當前工作目錄。
    
        [devalone@devalone bin]$ pwd
        /usr/bin
    
    
    ● 相對文件路徑
    -------------------------------------------------------------------------------------------------------------------------------------
    相對文件路徑允許用戶指定一個基於當前位置的目標文件路徑。相對文件路徑不以代表根目錄的正斜線 (/) 開頭,而是以目錄名或是一個特殊的字符
    開始。例如當前位於 home 目錄,想切換到 devel 子目錄,可以使用 cd 命令加上一個相對文件路徑:
        [devalone@devalone ~]$ pwd
        /home/devalone

        [devalone@devalone ~]$ cd devel
        [devalone@devalone devel]$ pwd
        /home/devalone/devel

    可以在任何包含子目錄的目錄中使用帶有相對文件路徑的 cd 命令。也可以使用一個特殊字符來表示相對目錄位置。

    有兩個特殊字符可用於相對文件路徑中:
        □ 單點符(.),表示當前目錄;
        □ 雙點符(..),表示當前目錄的父目錄。
    可以使用單點符,但對於 cd 命令來說沒什麼意義。雙點符在目錄層級中移動時非常便利。如:
    
        [devalone@devalone devel]$ pwd
        /home/devalone/devel
        [devalone@devalone devel]$ cd ../repo
        [devalone@devalone repo]$

    

3.2 文件和目錄列表
-----------------------------------------------------------------------------------------------------------------------------------------
要想知道系統中有哪些文件,可以使用列表命令(ls)。


ls命令最基本的形式會顯示當前目錄下的文件和目錄:

    [devalone@devalone study]$ ls
    junit-4.11-javadoc  junit-4.11-javadoc.jar  junit-in-action-II  shell-script

可用帶 -F 參數的 ls 命令輕鬆區分文件和目錄

    junit-4.11-javadoc/  junit-4.11-javadoc.jar  junit-in-action-II/  shell-script/

-F 參數在目錄名後加了正斜線 (/),以方便用戶在輸出中分辨它們。類似地,它會在可執行文件(比如上面的my_script文件) 的後面加個星號,以便用戶找出
可在系統上運行的文件。

要把隱藏文件和普通文件及目錄一起顯示出來,要用到 -a 參數。

-l 參數會產生長列表格式的輸出,包含了目錄中每個文件的更多相關信息。

    [devalone@devalone shell-script]$ ls -l
    總用量 96
    drwxrwxr-x. 2 devalone devalone 4096 1月   2 12:16 12
    drwxrwxr-x. 2 devalone devalone 4096 1月   2 17:17 13
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 14
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 15
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 16
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 17
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 18
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 16:06 19
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 20
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 21
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 22
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 23
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 14:40 24
    -rwxrwxr-x. 1 devalone devalone  104 1月   2 11:32 test10.sh
    -rwxrwxr-x. 1 devalone devalone  150 1月   2 11:32 test11.sh
    -rwxrwxr-x. 1 devalone devalone  177 1月   2 11:32 test12.sh
    -rwxrwxr-x. 1 devalone devalone  109 1月   2 11:32 test13.sh
    -rwxrwxr-x. 1 devalone devalone  152 1月   2 11:32 test1.sh
    -rwxrwxr-x. 1 devalone devalone  123 1月   2 11:32 test2.sh
    -rwxrwxr-x. 1 devalone devalone  159 1月   2 11:32 test3.sh
    -rwxrwxr-x. 1 devalone devalone  123 1月   2 11:32 test4.sh
    -rwxrwxr-x. 1 devalone devalone   68 1月   2 11:32 test5.sh
    -rwxrwxr-x. 1 devalone devalone   73 1月   2 11:32 test9.sh
    -rw-rw-r--. 1 devalone devalone   72 1月   7 13:15 testfile


    
    ● 過濾輸出列表
    -------------------------------------------------------------------------------------------------------------------------------------
    ls 命令支持在命令行中定義過濾器,它會用過濾器來決定應該在輸出中顯示哪些文件或目錄。這個過濾器就是一個進行簡單的文本匹配的字符串。可以
    用在命令行參數之後:
    
        [devalone@devalone shell-script]$ ls -l test9.sh
        -rwxrwxr-x. 1 devalone devalone 73 1月   2 11:32 test9.sh

    當指定特定文件的名稱作爲過濾器時, ls 命令只會顯示該文件的信息。有時可能不知道要找的那個文件的確切名稱,可以使用通配符匹配過濾。 ls
    命令能夠識別標準通配符,並在過濾器中用它們進行模式匹配:
    
        □ 問號(?)代表一個字符;
         □ 星號(*)代表零個或多個字符。

    示例:
        [devalone@devalone shell-script]$ ls -l test1?.sh
        -rwxrwxr-x. 1 devalone devalone 104 1月   2 11:32 test10.sh
        -rwxrwxr-x. 1 devalone devalone 150 1月   2 11:32 test11.sh
        -rwxrwxr-x. 1 devalone devalone 177 1月   2 11:32 test12.sh
        -rwxrwxr-x. 1 devalone devalone 109 1月   2 11:32 test13.sh

        [devalone@devalone shell-script]$ ls -l test*.sh
        -rwxrwxr-x. 1 devalone devalone 104 1月   2 11:32 test10.sh
        -rwxrwxr-x. 1 devalone devalone 150 1月   2 11:32 test11.sh
        -rwxrwxr-x. 1 devalone devalone 177 1月   2 11:32 test12.sh
        -rwxrwxr-x. 1 devalone devalone 109 1月   2 11:32 test13.sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
        -rwxrwxr-x. 1 devalone devalone 159 1月   2 11:32 test3.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test4.sh
        -rwxrwxr-x. 1 devalone devalone  68 1月   2 11:32 test5.sh
        -rwxrwxr-x. 1 devalone devalone  73 1月   2 11:32 test9.sh

    在過濾器中使用星號和問號被稱爲文件擴展匹配((file globbing), 指的是使用通配符進行模式匹配的過程。通配符正式的名稱爲元字符通配符
    (metacharacter wildcards)。除了星號和問號之外,還有更多的元字符通配符可用於文件擴展匹配,可以使用中括號。

        [devalone@devalone shell-script]$ ls -l test[12].sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
    
    也可以指定字符範圍,如 [1-3]:
        
        [devalone@devalone shell-script]$ ls -l test[1-3].sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
        -rwxrwxr-x. 1 devalone devalone 159 1月   2 11:32 test3.sh

    可以使用感嘆號(!) 將不需要的內容排除:

        [devalone@devalone shell-script]$ ls -l test[!3].sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test4.sh
        -rwxrwxr-x. 1 devalone devalone  68 1月   2 11:32 test5.sh
        -rwxrwxr-x. 1 devalone devalone  73 1月   2 11:32 test9.sh


3.3 處理文件
-----------------------------------------------------------------------------------------------------------------------------------------

 

3.3.1 創建文件
-----------------------------------------------------------------------------------------------------------------------------------------
可以使用 touch 命令創建空文件:

    [devalone@devalone shell-script]$ touch test
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:09 test

touch命令還可用來改變文件的修改時間。這個操作並不需要改變文件的內容。
    
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:09 test
    [devalone@devalone shell-script]$ touch test
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:10 test

 

3.3.2 複製文件
-----------------------------------------------------------------------------------------------------------------------------------------
cp 命令,在文件系統中將文件和目錄從一個位置複製到另一個位置。
基本用法:

    cp source destination

cp命令需要兩個參數——源對象和目標對象:當source和destination參數都是文件名時,cp命令將源文件複製成一個新文件,並且以
destination命名。新文件就像全新的文件一樣,有新的修改時間。

    [devalone@devalone shell-script]$ cp test test2
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:10 test
    [devalone@devalone shell-script]$ ls -l test2
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:15 test2

如果目標文件已經存在,cp 命令可能並不會提醒這一點。最好是加上 -i 選項,強制 shell 詢問是否需要覆蓋已有文件。

    [devalone@devalone shell-script]$ cp -i test test2
    cp:是否覆蓋'test2'? n

前面介紹了特殊符號可以用在相對文件路徑中。其中的單點符(.) 就很適合用於 cp 命令。記住,單點符表示當前工作目錄。

    [devalone@devalone shell-script]$ cp -i /etc/sysconfig/network .
    [devalone@devalone shell-script]$ ls -l network
    -rw-rw-r--. 1 devalone devalone 22 7月   2 19:21 network

cp命令的 -R 參數威力強大。可以用它在一條命令中遞歸地複製整個目錄的內容。

    [devalone@devalone shell-script]$ cp -R 12 12-test

在執行 cp –R 命令之前,目錄 12-test 並不存在。它是隨着 cp –R 命令被創建的,整個 12 目錄中的內容都被複制到其中。

也可以在cp命令中使用通配符:

    [devalone@devalone shell-script]$ mkdir dirsh
    [devalone@devalone shell-script]$ cp test?.sh dirsh/
    [devalone@devalone shell-script]$ ll dirsh
    總用量 24
    -rwxrwxr-x. 1 devalone devalone 152 7月   2 19:32 test1.sh
    -rwxrwxr-x. 1 devalone devalone 123 7月   2 19:32 test2.sh
    -rwxrwxr-x. 1 devalone devalone 159 7月   2 19:32 test3.sh
    -rwxrwxr-x. 1 devalone devalone 123 7月   2 19:32 test4.sh
    -rwxrwxr-x. 1 devalone devalone  68 7月   2 19:32 test5.sh
    -rwxrwxr-x. 1 devalone devalone  73 7月   2 19:32 test9.sh
    

3.3.3 製表鍵(tab)自動補全
-----------------------------------------------------------------------------------------------------------------------------------------
製表鍵(tab)自動補全功能允許在輸入文件名或目錄名時按一下製表鍵,讓 shell 將內容補充完整。

    [devalone@devalone shell-script]$ cp network-functions ff

上面例子輸入 cp net,然後按下 [tab] 鍵,shell 將整個文件名剩下的部分自動補全。當然目標還是要自己輸入的。


3.3.4 鏈接文件
-----------------------------------------------------------------------------------------------------------------------------------------
鏈接是目錄中指向文件真實位置的佔位符。在 Linux 中有兩種不同類型的文件鏈接:

    □ 符號鏈接
    □ 硬鏈接
    
符號鏈接就是一個實實在在的文件,它指向存放在虛擬目錄結構中某個地方的另一個文件。這兩個通過符號鏈接在一起的文件,彼此內容並不相同。

要創建一個符號鏈接,原始文件必須事先存在。然後使用 ln 命令及 -s 選項創建:

    [devalone@devalone shell-script]$ ln -s testfile testfile_s1
    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile
    lrwxrwxrwx. 1 devalone devalone  8 7月   2 19:51 testfile_s1 -> testfile
    [devalone@devalone shell-script]$

注意符號鏈接的名字 testfile_s1 位於 ln 命令中的第二個參數位置上。顯示在長列表中符號文件名後的->符號表明該文件是鏈接到文件 testfile 上的
一個符號鏈接。

另外還要注意的是,符號鏈接的文件大小與數據文件的文件大小。符號鏈接 testfile_s1 只有 8 個字節,而 testfile 有 72 個字節。這是因爲
testfile_s1 僅僅只是指向 testfile 而已。它們的內容並不相同,是兩個完全不同的文件。

硬鏈接會創建獨立的虛擬文件,其中包含了原始文件的信息及位置。但是它們從根本上而言是同一個文件。引用硬鏈接文件等同於引用了源文件。要創建硬鏈接
原始文件也必須事先存在,只不過這次使用 ln 命令時不再需要加入額外的參數。

    [devalone@devalone shell-script]$ ln test9.sh test9.sh_h1
    [devalone@devalone shell-script]$ ls -li test9.sh*
    1977755 -rwxrwxr-x. 2 devalone devalone 73 1月   2 11:32 test9.sh
    1977755 -rwxrwxr-x. 2 devalone devalone 73 1月   2 11:32 test9.sh_h1

在上面的例子中,我們使用 ls -li 命令顯示了 test9.sh* 的 inode 編號以及長列表。注意,帶有硬鏈接的文件共用 inode 編號。這是因爲它們終歸是
同一個文件。還要注意的是,鏈接計數(列表中第三項) 顯示這兩個文件都有兩個鏈接。另外,它們的文件大小也一模一樣。

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    只能對處於同一存儲媒體的文件創建硬鏈接。要想在不同存儲媒體的文件之間創建鏈接,只能使用符號鏈接。
    


3.3.5 重命名文件
-----------------------------------------------------------------------------------------------------------------------------------------
在Linux中,重命名文件稱爲移動(moving)。mv命令可以將文件和目錄移動到另一個位置或重新命名。

    [devalone@devalone shell-script]$ ll -i testfile*
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

    [devalone@devalone shell-script]$ mv testfile testfilezz

    [devalone@devalone shell-script]$ ls -li testfile*
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfilezz


注意,移動文件會將文件名從 testfile 更改爲 testfilezz,但 inode 編號和時間戳保持不變。這是因爲 mv 隻影響文件名。

也可以使用mv來移動文件的位置:

    [devalone@devalone shell-script]$ mv testfilezz ~/devel/
    [devalone@devalone shell-script]$ ls -li testfile*
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

    [devalone@devalone shell-script]$ ls -li ~/devel/testfile*
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 /home/devalone/devel/testfilezz

也可以使用mv命令移動文件位置並修改文件名稱,這些操作只需一步就能完成:

    [devalone@devalone shell-script]$ mv ~/devel/testfilezz ./testfile
    [devalone@devalone shell-script]$ ls -li testfile*
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

也可以使用mv命令移動整個目錄及其內容:
    [devalone@devalone shell-script]$ ls -ld network-scripts
    drwxr-xr-x. 2 devalone devalone 4096 7月   2 19:26 network-scripts

    [devalone@devalone shell-script]$ mv network-scripts  network-scripts-zz
    [devalone@devalone shell-script]$ ls -ld network-scripts*
    drwxr-xr-x. 2 devalone devalone 4096 7月   2 19:26 network-scripts-zz
    
    
3.3.6 刪除文件
-----------------------------------------------------------------------------------------------------------------------------------------
在 Linux 中,刪除(deleting)叫作移除(removing)。bash shell中刪除文件的命令是 rm。rm 命令的基本格式非常簡單:

    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

    [devalone@devalone shell-script]$ rm -i testfile2
    rm:是否刪除普通文件 'testfile2'?y
    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile

注意,-i 命令參數提示是不是要真的刪除該文件。bash shell 中沒有回收站或垃圾箱,文件一旦刪除,就無法再找回。因此,在使用 rm 命令時,要養成
總是加入 -i 參數的好習慣。

也可以使用通配符刪除成組的文件:

    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:24 testfile-zz
    [devalone@devalone shell-script]$ rm -i testfile*
    rm:是否刪除普通文件 'testfile'?n
    rm:是否刪除普通文件 'testfile-zz'?

rm 命令的另外一個特性是,如果要刪除很多文件且不受提示符的打擾,可以用 -f 參數強制刪除。千萬小心!

 

3.4 處理目錄
-----------------------------------------------------------------------------------------------------------------------------------------
在Linux中,有些命令(比如cp命令)對文件和目錄都有效,而有些只對目錄有效。


3.4.1 創建目錄
-----------------------------------------------------------------------------------------------------------------------------------------
使用 mkdir 命令:

    [devalone@devalone shell_test]$ mkdir dir
    [devalone@devalone shell_test]$ ll
    總用量 4
    drwxrwxr-x. 2 devalone devalone 4096 7月   3 10:18 new_dir

要想同時創建多個目錄和子目錄,需要加入 -p 參數:

    [devalone@devalone shell_test]$ mkdir -p new_dir/sub_dir/under_dir
    [devalone@devalone shell_test]$ ls -R
    .:
    new_dir

    ./new_dir:
    sub_dir

    ./new_dir/sub_dir:
    under_dir

    ./new_dir/sub_dir/under_dir:

 

3.4.2 刪除目錄
-----------------------------------------------------------------------------------------------------------------------------------------
刪除目錄的基本命令是 rmdir,默認情況下,rmdir 命令只刪除空目錄。

    [devalone@devalone shell_test]$ rmdir new_dir/sub_dir/under_dir/
    [devalone@devalone shell_test]$ ls -R
    .:
    new_dir

    ./new_dir:
    sub_dir

    ./new_dir/sub_dir:


也可以在整個非空目錄上使用rm命令。使用 -r 選項使得命令可以向下進入目錄,刪除其中的文件,然後再刪除目錄本身。一次性刪除目錄及其所有內容的
終極大法就是使用帶有 -r 參數和 -f 參數的 rm 命令。

    [devalone@devalone shell_test]$ touch new_dir/new_file
    [devalone@devalone shell_test]$ ls -R
    .:
    new_dir

    ./new_dir:
    new_file  sub_dir

    ./new_dir/sub_dir:
    [devalone@devalone shell_test]$ rm -rf new_dir
    [devalone@devalone shell_test]$ ll
    總用量 0

    
    
3.5 查看文件內容
-----------------------------------------------------------------------------------------------------------------------------------------


3.5.1 查看文件類型
-----------------------------------------------------------------------------------------------------------------------------------------
file 命令是一個便捷工具。它能夠探測文件的內部,並決定文件是什麼類型的:

    [devalone@devalone shell_test]$ file testfile
    testfile: ASCII text

測試目錄:
    [devalone@devalone shell_test]$ file new_dir
    new_dir: directory

測試鏈接:
    [devalone@devalone shell_test]$ ln -s testfile ln_test    
    [devalone@devalone shell_test]$ file ln_test
    ln_test: symbolic link to testfile

測試腳本文件:
    [devalone@devalone shell_test]$ file test1.sh
    test1.sh: Bourne-Again shell script, ASCII text executable

測試二進制可執行文件:

    [devalone@devalone shell_test]$ file /bin/ls
    /bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
    for GNU/Linux 2.6.32, BuildID[sha1]=0ac5c509289d650534ce80cdbf5b72744b5c5f3d, stripped

    
    
3.5.2 查看整個文件
-----------------------------------------------------------------------------------------------------------------------------------------


    cat 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    [devalone@devalone shell_test]$ cat testfile
    This is the first line.
    This is the second line.
    This is the third line.

    
    -n 參數會給所有的行加上行號:
    [devalone@devalone shell_test]$ cat -n testfile
     1  This is the first line.
     2  This is the second line.
     3  This is the third line.
     4

    如果只想給有文本的行加上行號,可以用 -b 參數,在檢查腳本時很有用:
    
     [devalone@devalone shell_test]$ cat -b test1.sh
     1  #!/bin/bash
     2  # This script displays the date and who's log on
     3  echo -n  "The time and date are: "
     4  date
     5  echo "Let's see who's logged into the system:"
     6  who

    如果不想讓製表符出現,可以用 -T 參數:-T 參數會用 ^I 字符組合去替換文中的所有制表符:
    [devalone@devalone shell_test]$ cat -T testfile
    This is the first line.
    This is the second line.
    This is the thir^Id line.

    
    
    more 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    more 命令會顯示文本文件的內容,但會在顯示每頁數據之後停下來:
    
        [devalone@devalone shell_test]$ more /etc/passwd
    
    more命令是分頁工具。瀏覽完之後,按 q 鍵退出。more命令只支持文本文件中的基本移動。如果要更多高級功能,可以試試 less 命令。
    
    
    less 命令
    -------------------------------------------------------------------------------------------------------------------------------------    
    less 命令實爲 more 命令的升級版。它提供了一些極爲實用的特性,能夠實現在文本文件中前後翻動,而且還有一些高級搜索功能。
    
    less命令的操作和more命令基本一樣,一次顯示一屏的文件文本。除了支持和 more 命令相同的命令集,它還包括更多的選項。
    
    可以輸入 man less 瀏覽對應的手冊頁。man 工具本身就是搭載 less 命令進行操作的。
    
    
    
3.5.3 查看部分文件
-----------------------------------------------------------------------------------------------------------------------------------------    
通常要查看的數據要麼在文本文件的開頭,要麼在文本文件的末尾。如果這些數據是在大型文件的起始部分,那就得等 cat 或 more 加載完整個文件
之後才能看到。如果數據是在文件的末尾(比如日誌文件),那可能需要翻過成千上萬行的文本才能到最後的內容。


    tail 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    tail命令會顯示文件最後幾行的內容(文件的“尾部”)。默認情況下,它會顯示文件的末尾10行。可以向tail命令中加入 -n 參數來修改所顯示的行數:
    
    [devalone@devalone shell_test]$ cat testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.

    [devalone@devalone shell_test]$ tail testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.

    [devalone@devalone shell_test]$ tail -n 2 testfile
    This is the third line.
    This is the fourth line.

    也可以將 -n 2 參數直接寫成 -2 形式:
    [devalone@devalone shell_test]$ tail -2 testfile
    This is the third line.
    This is the fourth line.

    
    head 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    會顯示文件開頭那些行的內容。默認情況下,它會顯示文件前10行的文本:

    [devalone@devalone shell_test]$ head testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.
    This is the 5th line.
    This is the 6th line.
    This is the 7th line.
    This is the 8th line.
    This is the 9th line.
    This is the 10th line.

    類似於 tail 命令,它也支持 -n 參數,這樣就可以指定想要顯示的內容了。這兩個命令都允許在 "-" 後面輸入想要顯示的行數:

    [devalone@devalone shell_test]$ head -5 testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.
    This is the 5th line.

 

4. 更多的 bash shell 命令
-----------------------------------------------------------------------------------------------------------------------------------------

 

4.1 監測程序
-----------------------------------------------------------------------------------------------------------------------------------------

 

4.1.1 探查進程
-----------------------------------------------------------------------------------------------------------------------------------------
當程序運行在系統上時,稱之爲進程(process)。要檢測這些進程,需要熟悉 ps 命令的用法,ps 命令好比工具中的瑞士軍刀,它能輸出運行在系統上的所有
程序的許多信息。隨着功能的強大而來的是其複雜性,ps 有數不清的參數,這或許是讓它成爲最難掌握的命令。大多數系統管理員在掌握了能提供需要的一組
參數之後,就一直堅持只使用這組參數。

默認情況下, ps 並不會提供全部的信息:只會顯示運行在當前控制檯下的屬於當前用戶的進程

[devalone@devalone shell_test]$ ps
  PID TTY          TIME CMD
 2373 pts/1    00:00:00 bash
 3108 pts/1    00:00:00 ps


Linux系統中使用的GNU ps命令支持3種不同類型的命令行參數:
    □ Unix風格的參數,前面加單連字符 "-";
    □ BSD風格的參數,前面不加連字符 "-";
    □ GNU風格的長參數,前面加雙連字符 "--"

以 Unix 風格的參數爲例說明:Unix 風格的參數是從貝爾實驗室開發的 AT&T Unix 系統上原有的 ps 命令繼承下來的。參數如下表所示:

    Unix風格的ps命令參數
    +---------------+-----------------------------------------------------------------------------------------
    | 參 數            |    描 述
    +---------------+-----------------------------------------------------------------------------------------
    | -A            | 顯示所有進程
    +---------------+-----------------------------------------------------------------------------------------
    | -N            | 顯示與指定參數不符的所有進程
    +---------------+-----------------------------------------------------------------------------------------
    | -a            | 顯示除控制進程(session leader①)和無終端進程外的所有進程
    +---------------+-----------------------------------------------------------------------------------------
    | -d            | 顯示除控制進程外的所有進程
    +---------------+-----------------------------------------------------------------------------------------
    | -e            | 顯示所有進程
    +---------------+-----------------------------------------------------------------------------------------
    | -C cmdlist    | 顯示包含在cmdlist列表中的進
    +---------------+-----------------------------------------------------------------------------------------
    | -G grplist    | 顯示組ID在grplist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -U userlist    | 顯示屬主的用戶ID在userlist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -g grplist    | 顯示會話或組ID在grplist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -p pidlist    | 顯示PID在pidlist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -s sesslist    | 顯示會話ID在sesslist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -t ttylist    | 顯示終端ID在ttylist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -u userlist    | 顯示有效用戶ID在userlist列表中的進程
    +---------------+-----------------------------------------------------------------------------------------
    | -F            | 顯示更多額外輸出(相對-f參數而言)
    +---------------+-----------------------------------------------------------------------------------------
    | -O format        | 顯示默認的輸出列以及format列表指定的特定列
    +---------------+-----------------------------------------------------------------------------------------
    | -M            | 顯示進程的安全信息
    +---------------+-----------------------------------------------------------------------------------------
    | -c            | 顯示進程的額外調度器信息
    +---------------+-----------------------------------------------------------------------------------------
    | -f            | 顯示完整格式的輸出
    +---------------+-----------------------------------------------------------------------------------------
    | -j            | 顯示任務信息
    +---------------+-----------------------------------------------------------------------------------------
    | -l            | 顯示長列表
    +---------------+-----------------------------------------------------------------------------------------
    | -o format        | 僅顯示由format指定的列
    +---------------+-----------------------------------------------------------------------------------------
    | -y            | 不要顯示進程標記(process flag,表明進程狀態的標記)
    +---------------+-----------------------------------------------------------------------------------------
    | -Z            | 顯示安全標籤(security context)信息
    +---------------+-----------------------------------------------------------------------------------------
    | -H            | 用層級格式來顯示進程(樹狀,用來顯示父進程)
    +---------------+-----------------------------------------------------------------------------------------
    | -n namelist    | 定義了WCHAN列顯示的值
    +---------------+-----------------------------------------------------------------------------------------
    | -w            | 採用寬輸出模式,不限寬度顯示
    +---------------+-----------------------------------------------------------------------------------------
    | -L            | 顯示進程中的線程
    +---------------+-----------------------------------------------------------------------------------------
    | -V            | 顯示 ps 命令的版本號
    +---------------+-----------------------------------------------------------------------------------------

還有很多... 更多內容查看 man ps

要查看系統上運行的所有進程,可用 -ef 參數組合:

    [devalone@devalone shell_test]$ ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 10:12 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 23
    root         2     0  0 10:12 ?        00:00:00 [kthreadd]
    root         4     2  0 10:12 ?        00:00:00 [kworker/0:0H]
    root         6     2  0 10:12 ?        00:00:00 [mm_percpu_wq]
    root         7     2  0 10:12 ?        00:00:00 [ksoftirqd/0]
    root         8     2  0 10:12 ?        00:00:00 [rcu_sched]
    root         9     2  0 10:12 ?        00:00:00 [rcu_bh]
    root        10     2  0 10:12 ?        00:00:00 [rcuos/0]
    root        11     2  0 10:12 ?        00:00:00 [rcuob/0]
...


這個例子用了兩個參數:-e 參數指定顯示所有運行在系統上的進程;-f 參數則擴展了輸出,這些擴展的列包含了有用的信息。說明如下:

    □ UID    :啓動這些進程的用戶。
    □ PID    :進程的進程ID。
    □ PPID    :父進程的進程號(如果該進程是由另一個進程啓動的)。
    □ C        :進程生命週期中的 CPU 利用率。
    □ STIME    :進程啓動時的系統時間。
    □ TTY    :進程啓動時的終端設備。
    □ TIME    :運行進程需要的累計 CPU 時間。
    □ CMD    :啓動的程序名稱。

上例中輸出了合理數量的信息,這也正是大多數系統管理員希望看到的。如果想要獲得更多的信息,可採用 -l 參數,它會產生一個長格式輸出:

    [devalone@devalone shell_test]$ ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S  1000  2373  2360  0  80   0 - 30530 wait   pts/1    00:00:00 bash
    0 R  1000  3148  2373  0  80   0 - 36971 -      pts/1    00:00:00 ps

其中:
    F    :內核分配給進程的系統標記。
    S    :進程的狀態(O代表正在運行;S代表在休眠;R代表可運行,正等待運行;Z代表殭屍進程,進程已結束但父進程已不存在;T代表停止)。
    PRI    :進程的優先級(越大的數字代表越低的優先級)。
    NI    :謙讓度值用來參與決定優先級。
    ADDR:進程的內存地址。
    SZ    :假如進程被換出,所需交換空間的大致大小。
    WCHAN:進程休眠的內核函數的地址。
    

    
4.1.2 實時監測進程
-----------------------------------------------------------------------------------------------------------------------------------------    
ps 命令雖然在收集運行在系統上的進程信息時非常有用,但也有不足之處:它只能顯示某個特定時間點的信息。

top 命令跟 ps 命令相似,能夠顯示進程信息,但它是實時顯示的。輸出的第一部分顯示的是系統的概況:第一行顯示了當前時間、系統的運行時間、登錄
的用戶數以及系統的平均負載。

    [devalone@devalone shell_test]$ top
    top - 12:24:00 up  2:11,  2 users,  load average: 0.00, 0.00, 0.00
    Tasks: 228 total,   1 running, 227 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.1 si,  0.0 st
    KiB Mem :  3921200 total,   597080 free,   781000 used,  2543120 buff/cache
    KiB Swap:  3932156 total,  3932156 free,        0 used.  2571428 avail Mem

      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
     1889 devalone  20   0 2590496 146404  69768 S   0.7  3.7   0:06.67 gnome-shell
     3177 devalone  20   0  156636   4332   3692 R   0.3  0.1   0:00.13 top
        1 root      20   0  196744   9172   5916 S   0.0  0.2   0:01.30 systemd
        2 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kthreadd
        4 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H
        6 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 mm_percpu_wq
        7 root      20   0       0      0      0 S   0.0  0.0   0:00.00 ksoftirqd/0
        8 root      20   0       0      0      0 S   0.0  0.0   0:00.68 rcu_sched
        9 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcu_bh
       10 root      20   0       0      0      0 S   0.0  0.0   0:00.26 rcuos/0
       11 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcuob/0
       12 root      rt   0       0      0      0 S   0.0  0.0   0:00.00 migration/0
       13 root      rt   0       0      0      0 S   0.0  0.0   0:00.01 watchdog/0

       ...

平均負載有 3 個值:最近 1 分鐘的、最近 5 分鐘的和最近 15 分鐘的平均負載。值越大說明系統的負載越高。由於進程短期的突發性活動,出現最近 1分
鐘的高負載值也很常見,但如果近 15 分鐘內的平均負載都很高,就說明系統可能有問題。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    Linux 系統管理的要點在於定義究竟到什麼程度纔算是高負載。這個值取決於系統的硬件配置以及系統上通常運行的程序。對某個系統來說是高負載的
    值可能對另一系統來說就是正常值。通常,如果系統的負載值超過了2,就說明系統比較繁忙了。


第二行顯示了進程概要信息—— top 命令的輸出中將進程叫作任務(task):有多少進程處在運行、休眠、停止或是僵化狀態(僵死狀態是指進程完成了,但
父進程沒有響應)。

下一行顯示了CPU的概要信息。top 根據進程的屬主(用戶還是系統)和進程的狀態(運行、空閒還是等待)將CPU利用率分成幾類輸出。

緊跟其後的兩行說明了系統內存的狀態。第一行說的是系統的物理內存:總共有多少內存,當前用了多少,還有多少空閒。後一行說的是同樣的信息,不過是
針對系統交換空間(如果分配了的話)的狀態而言的。

最後一部分顯示了當前運行中的進程的詳細列表,有些列跟 ps 命令的輸出類似。

    PID    :進程的ID。
    USER:進程屬主的名字。
    PR    :進程的優先級。
    NI    :進程的謙讓度值。
    VIRT:進程佔用的虛擬內存總量。
    RES    :進程佔用的物理內存總量。
    SHR    :進程和其他進程共享的內存總量。
    S    :進程的狀態(D代表可中斷的休眠狀態,R代表在運行狀態,S代表休眠狀態,T代表跟蹤狀態或停止狀態,Z代表僵化狀態)。
    %CPU:進程使用的CPU時間比例。
    %MEM:進程使用的內存佔可用內存的比例。
    TIME+:自進程啓動到目前爲止的CPU時間總量。
    COMMAND:進程所對應的命令行名稱,也就是啓動的程序名。    

默認情況下,top 命令在啓動時會按照 %CPU 值對進程排序。可以在 top 運行時使用多種交互命令重新排序。每個交互式命令都是單字符,在 top 命令
運行時鍵入可改變 top 的行爲。鍵入 f 允許選擇對輸出進行排序的字段,鍵入 d 允許修改輪詢間隔。鍵入q可以退出top。

 

4.1.3 結束進程
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 沿用了 Unix 進行進程間通信的方法。在 Linux 中,進程之間通過信號來通信。進程的信號就是預定義好的一個消息,進程能識別它並決定忽略還是
作出反應。進程如何處理信號是由開發人員通過編程來決定的。大多數編寫完善的程序都能接收和處理標準 Unix 進程信號。這些信號定義如下表所示:

查閱信號定義:
    
    man 7 signal

    常見 Linux 進程信號
    +-------+-----------+--------------------------------------------------------------
    | 信 號    | 名 稱        | 描 述
    +-------+-----------+--------------------------------------------------------------
    | 1        | SIGHUP     | 掛起
    +-------+-----------+--------------------------------------------------------------
    | 2        | SIGINT    | 中斷
    +-------+-----------+--------------------------------------------------------------
    | 3        | SIGQUIT    | 結束運行
    +-------+-----------+--------------------------------------------------------------
    | 4        | SIGILL     | 無效指令
    +-------+-----------+--------------------------------------------------------------
    | 9        | SIGKILL    | 無條件終止
    +-------+-----------+--------------------------------------------------------------
    | 11    | SIGSEGV    | 段錯誤,非法內存引用
    +-------+-----------+--------------------------------------------------------------
    | 15    | SIGTERM    | 儘可能終止,Termination signal
    +-------+-----------+--------------------------------------------------------------
    | 18    |  SIGCONT    | 在 SIGSTOP 或 TSTP之後恢復執行
    +-------+-----------+--------------------------------------------------------------
    | 19    | SIGSTOP    | 無條件停止運行,但不終止
    +-------+-----------+--------------------------------------------------------------


    ● kill 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    kill 命令可通過進程 ID(PID)給進程發信號。默認情況下,kill命令會向命令行中列出的全部 PID 發送一個 TERM 信號。只能用進程的PID而不能用
    命令名,所以 kill 命令有時並不好用。要發送進程信號,必須是進程的屬主或登錄爲 root 用戶。
    
        [devalone@devalone ~]$ kill 3318
        
    SIGTERM 信號告訴進程可能的話就停止運行。不過,如果有不服管教的進程,通常會忽略這個請求。如果要強制終止,-s 參數支持指定其他信號(用
    信號名或信號值)。

        [devalone@devalone ~]$ kill -s 9 3393
    
    或者寫成:
    
        [devalone@devalone ~]$ kill -9 3393
    
    
    
    ● killall 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    killall 命令非常強大,它支持通過進程名而不是 PID 來結束進程。killall 命令也支持通配符,這在系統因負載過大而變得很慢時很有用。
    
        [devalone@devalone ~]$ killall -9 top


    
4.2 檢測磁盤空間
-----------------------------------------------------------------------------------------------------------------------------------------


4.2.1 掛載存儲媒體
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 文件系統將所有的磁盤都併入一個虛擬目錄下。在使用新的存儲媒體之前,需要把它放到虛擬目錄下。這項工作稱爲掛載(mounting)。

在圖形化桌面環境裏,大多數 Linux 發行版都能自動掛載特定類型的可移動存儲媒體。可移動存儲媒體指的是可從 PC 上輕易移除的媒體,比如 CD-ROM、
軟盤和 U盤。


    ● mount 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    默認情況下,mount 命令會輸出當前系統上掛載的設備列表。
    
    [devalone@devalone ~]$ mount
    /dev/mapper/fedora_devalone-root on / type ext4 (rw,relatime,seclabel,data=ordered)
    selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime)
    /dev/mapper/fedora_devalone-home on /home type ext4 (rw,relatime,seclabel,data=ordered)
    /dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
    /dev/mapper/fedora_devalone-var on /var type ext4 (rw,relatime,seclabel,data=ordered)

    ...
    
    mount 命令提供如下四部分信息:
    
    □ 媒體的設備文件名
  □ 媒體掛載到虛擬目錄的掛載點
     □ 文件系統類型
     □ 已掛載媒體的訪問狀態
    
    要手動在虛擬目錄中掛載設備,需要以 root 用戶身份登錄,或是以 root 用戶身份運行 sudo 命令。下面是手動掛載媒體設備的基本命令:
    
        mount -t type device directory
        
    type 參數指定了磁盤被格式化的文件系統類型。Linux 可以識別非常多的文件系統類型。如果是和 Windows PC 共用這些存儲設備,通常得使用下列
    文件系統類型:
    
    □ vfat:Windows長文件系統。
    □ ntfs:Windows NT、XP、Vista 以及 Windows 7 中廣泛使用的高級文件系統。
    □ iso9660:標準CD-ROM文件系統。
    
    
    後面兩個參數定義了該存儲設備的設備文件的位置以及掛載點在虛擬目錄中的位置。如,手動將 U盤 /dev/sdb1 掛載到 /media/disk,可用下面的命令
    
        mount -t vfat /dev/sdb1 /media/disk
    
    -a 參數掛載 /etc/fstab 文件中指定的所有文件系統。
    -o 參數允許在掛載文件系統時添加一些以逗號分隔的額外選項,以下是常用選項:
    
        □ ro:以只讀形式掛載。
        □ rw:以讀寫形式掛載。
        □ user:允許普通用戶掛載文件系統。
        □ check=none:掛載文件系統時不進行完整性校驗。
        □ loop:掛載一個文件。
    
    
    ● umount 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    從 Linux 系統上移除一個可移動設備時,不能直接從系統上移除,而應該先卸載。
    
    Linux 上不能直接彈出已掛載的 CD。如果在從光驅中移除 CD 時遇到麻煩,通常是因爲該 CD 還掛載在虛擬目錄裏。先卸載它,然後再去嘗試彈出。
    
    umount命令的格式:
    
        umount [directory | device ]
    
    umount 命令支持通過設備文件或者是掛載點來指定要卸載的設備。如果有任何程序正在使用設備上的文件,系統就不會允許卸載它:
    

    
4.2.2 使用 df 命令
-----------------------------------------------------------------------------------------------------------------------------------------
有時需要知道在某個設備上還有多少磁盤空間。df 命令可以很方便地查看所有已掛載磁盤的使用情況。

    [devalone@devalone shell_test]$ df
    文件系統                             1K-塊      已用      可用 已用% 掛載點
    devtmpfs                           1945972         0   1945972    0% /dev
    tmpfs                              1960600       328   1960272    1% /dev/shm
    tmpfs                              1960600      1600   1959000    1% /run
    tmpfs                              1960600         0   1960600    0% /sys/fs/cgroup
    /dev/mapper/fedora_devalone-root  51475068   8518008  40319236   18% /
    tmpfs                              1960600       116   1960484    1% /tmp
    /dev/mapper/fedora_devalone-home 103081248  47583664  50238320   49% /home
    /dev/sda1                           487652    181444    276512   40% /boot
    /dev/mapper/fedora_devalone-var  321389700 128665696 176375232   43% /var
    tmpfs                               392120        16    392104    1% /run/user/42
    tmpfs                               392120        24    392096    1% /run/user/1000

df 命令有一些命令行參數可用,但基本上不會用到。一個常用的參數是 -h。它會把輸出中的磁盤空間按照用戶易讀的形式顯示,通常用 M 來替代兆字節,
用 G 替代吉字節。

    [devalone@devalone shell_test]$ df -h
    文件系統                          容量  已用  可用 已用% 掛載點
    devtmpfs                          1.9G     0  1.9G    0% /dev
    tmpfs                             1.9G  328K  1.9G    1% /dev/shm
    tmpfs                             1.9G  1.6M  1.9G    1% /run
    tmpfs                             1.9G     0  1.9G    0% /sys/fs/cgroup
    /dev/mapper/fedora_devalone-root   50G  8.2G   39G   18% /
    tmpfs                             1.9G  116K  1.9G    1% /tmp
    /dev/mapper/fedora_devalone-home   99G   46G   48G   49% /home
    /dev/sda1                         477M  178M  271M   40% /boot
    /dev/mapper/fedora_devalone-var   307G  123G  169G   43% /var
    tmpfs                             383M   16K  383M    1% /run/user/42
    tmpfs                             383M   24K  383M    1% /run/user/1000

 

4.2.3 使用 du 命令
-----------------------------------------------------------------------------------------------------------------------------------------
du 命令可以顯示某個特定目錄(默認情況下是當前目錄)的磁盤使用情況。這一方法可用來快速判斷系統上某個目錄下是否有超大文件。

默認情況下,du 命令會顯示當前目錄下所有的文件、目錄和子目錄的磁盤使用情況,它會以磁盤塊爲單位來表明每個文件或目錄佔用了多大存儲空間。對
標準大小的目錄來說,這個輸出會是一個比較長的列表。

    [devalone@devalone shell-script]$ du
    64      ./15
    72      ./13
    24      ./24
    48      ./16
    12      ./.git/refs/remotes/origin
    16      ./.git/refs/remotes
    8       ./.git/refs/heads
    4       ./.git/refs/tags
    ...

每行輸出左邊的數值是每個文件或目錄佔用的磁盤塊數。注意,這個列表是從目錄層級的最底部開始,然後按文件、子目錄、目錄逐級向上。這麼用 du 命令
(不加參數,用默認參數)作用並不大,下面是能讓du命令用起來更方便的幾個命令行參數。

    -c:顯示所有已列出文件總的大小。
     -h:按用戶易讀的格式輸出大小,即用 K 替代千字節,用 M 替代兆字節,用 G 替代吉字節。
    -s:顯示每個輸出參數的總計。

 

4.3 處理數據文件
-----------------------------------------------------------------------------------------------------------------------------------------


4.3.1 排序數據
-----------------------------------------------------------------------------------------------------------------------------------------
處理大量數據時的一個常用命令是 sort 命令,sort 命令是對數據進行排序的。默認情況下,sort 命令按照會話指定的默認語言的排序規則對文本文件中的
數據行排序。

    [devalone@devalone shell_test]$ cat sortfile
    1
    2
    100
    45
    3
    10
    145
    75

    [devalone@devalone shell_test]$ sort sortfile
    1
    10
    100
    145
    2
    3
    45
    75
默認情況下,sort 命令會把數字當做字符來執行標準的字符排序,產生的輸出可能根本就不是要的。解決這個問題可用 -n 參數,它會告訴 sort 命令
把數字識別成數字而不是字符,並且按值排序。

    [devalone@devalone shell_test]$ sort -n sortfile
    1
    2
    3
    10
    45
    75
    100
    145

如期所願了。

另一個常用的參數是 -M,按月排序。Linux 的日誌文件經常會在每行的起始位置有一個時間戳,用來表明事件是什麼時候發生的。-M 參數能識別三字符的
月份名,並相應地排序。

    [devalone@devalone shell_test]$ sort -M file
    Jan
    Feb
    Mar
    Apr
    May
    Jun
    Jul
    Aug
    Sep
    Oct
    Nov
    Dec

-k --key=POS1[,POS2] 排序從POS1位置開始;如果指定了POS2的話,到POS2位置結束。
-t --field-separator=SEP 指定一個用來區分鍵位置的字符。
-r --reverse 反序排序(升序變成降序)。

-k 和 -t 參數在對按字段分隔的數據進行排序時非常有用,例如/etc/passwd文件。可以用 -t 參數來指定字段分隔符,然後用-k 參數來指定排序的字段。
如對 /etc/passwd 文件根據用戶 ID 進行數值排序,可以這麼做:

    [devalone@devalone shell_test]$ sort -t ':' -k 3 -n /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    ...

-n 參數在排序數值時非常有用,比如 du 命令的輸出:

    [devalone@devalone shell-script]$ du -sh * | sort -nr
    232K    network-scripts-zz
    172K    12
    128K    14
    72K     13
    68K     17
    64K     15
    56K     19
    52K     21
    52K     20
    48K     16
    32K     22
    28K     dirsh
    24K     24
    16K     23
    12K     18
    4.0K    testfile-zz
    4.0K    testfile

 

4.3.2 搜索數據
-----------------------------------------------------------------------------------------------------------------------------------------
經常需要在大文件中找一行數據,而這行數據又埋藏在文件的中間。這時並不需要手動翻看整個文件,用 grep 命令來幫助查找就行了。grep 命令的命令
格式如下:

    grep [options] pattern [file]

grep 命令會在輸入或指定的文件中查找包含匹配指定模式的字符的行。grep 的輸出就是包含了匹配模式的行。

    [devalone@devalone shell_test]$ grep 8th testfile
    This is the 8th line.

    [devalone@devalone shell_test]$ grep d testfile
    This is the second line.
    This is the third line.

如果要進行反向搜索(輸出不匹配該模式的行),可加 -v 參數:

    [devalone@devalone shell_test]$ grep -v d testfile
    This is the first line.
    This is the fourth line.
    This is the 5th line.
    This is the 6th line.
    This is the 7th line.
    This is the 8th line.
    This is the 9th line.
    This is the 10th line.
    This is the 11th line.
    This is the 12th line.

要顯示匹配模式的行所在的行號,可加 -n 參數。
    [devalone@devalone shell_test]$ grep -n d testfile
    2:This is the second line.
    3:This is the third line.

只要知道有多少行含有匹配的模式,可用 -c 參數。
    [devalone@devalone shell_test]$ grep -c d testfile
    2

    
如果要指定多個匹配模式,可用 -e 參數來指定每個模式:

    [devalone@devalone shell_test]$ grep -e d -e u testfile
    This is the second line.
    This is the third line.
    This is the fourth line.

    
默認情況下,grep 命令用基本的 Unix 風格正則表達式來匹配模式。Unix 風格正則表達式採用特殊字符來定義怎樣查找匹配的模式。正則表達式的詳細內容
會在後面章節說明。

使用正則表達式的例子:

    [devalone@devalone shell_test]$ grep [du] testfile
    This is the second line.
    This is the third line.
    This is the fourth line.
    
egrep 命令是 grep 的一個衍生,支持 POSIX 擴展正則表達式。POSIX 擴展正則表達式含有更多的可以用來指定匹配模式的字符。
fgrep 則是另外一個版本,支持將匹配模式指定爲用換行符分隔的一列固定長度的字符串。這樣就可以把這列字符串放到一個文件中,然後在 fgrep 命令中
用其在一個大型文件中搜索字符串了。


4.3.3 壓縮數據
-----------------------------------------------------------------------------------------------------------------------------------------


    Linux文件壓縮工具
    +-----------+---------------+------------------------------------------------------------
    | 工 具        | 文件擴展名    | 描 述
    +-----------+---------------+------------------------------------------------------------
    | bzip2        | .bz2            | 採用Burrows-Wheeler塊排序文本壓縮算法和霍夫曼編碼
    +-----------+---------------+------------------------------------------------------------
    | compress    | .Z            | 最初的Unix文件壓縮工具,已經快沒人用了
    +-----------+---------------+------------------------------------------------------------
    | gzip        | .gz            | GNU壓縮工具,用Lempel-Ziv編碼
    +-----------+---------------+------------------------------------------------------------
    | zip        | .zip            | Windows上PKZIP工具的Unix實現
    +-----------+---------------+------------------------------------------------------------

gzip軟件包是GNU項目的產物,軟件包含有下面的工具:

    gzip:用來壓縮文件。
    gzcat:用來查看壓縮過的文本文件的內容。
    gunzip:用來解壓文件。    

這些工具基本上跟 bzip2 工具的用法一樣。

    [devalone@devalone shell_test]$ gzip testfile
    [devalone@devalone shell_test]$ ll testfile*
    -rw-rw-r--. 1 devalone devalone 105 7月   3 11:26 testfile.gz

gzip 命令會壓縮在命令行指定的文件。也可以在命令行指定多個文件名甚至用通配符來一次性批量壓縮文件。
    [devalone@devalone shell_test]$ gunzip test*

 

4.3.4 歸檔數據
-----------------------------------------------------------------------------------------------------------------------------------------
雖然zip命令能夠很好地將數據壓縮和歸檔進單個文件,但它不是 Unix 和 Linux 中的標準歸檔工具。Unix 和 Linux 上最廣泛使用的歸檔工具是 tar 命令

tar 命令最開始是用來將文件寫到磁帶設備上歸檔的,然而它也能把輸出寫到文件裏,這種用法在 Linux 上已經普遍用來歸檔數據了。

下面是tar命令的格式:

    tar function [options] object1 object2 ...

function 參數定義了 tar 命令應該做什麼,如表所示:

    tar命令的功能
    +-------+---------------+--------------------------------------------------------------------------------
    | 功 能    | 長 名 稱        | 描 述
    +-------+---------------+--------------------------------------------------------------------------------
    | -A    | --concatenate    | 將一個已有tar歸檔文件追加到另一個已有tar歸檔文件
    +-------+---------------+--------------------------------------------------------------------------------
    | -c    | --create        | 創建一個新的tar歸檔文件
    +-------+---------------+--------------------------------------------------------------------------------
    | -d    | --diff        | 檢查歸檔文件和文件系統的不同之處
    +-------+---------------+--------------------------------------------------------------------------------
    | -r    | --append        | 追加文件到已有tar歸檔文件末尾
    +-------+---------------+--------------------------------------------------------------------------------
    | -t    | --list        | 列出已有tar歸檔文件的內容
    +-------+---------------+--------------------------------------------------------------------------------
    | -u    | --update        | 將比tar歸檔文件中已有的同名文件新的文件追加到該tar歸檔文件中
    +-------+---------------+--------------------------------------------------------------------------------
    | -x    | --extract        | 從已有tar歸檔文件中提取文件
    +-------+---------------+--------------------------------------------------------------------------------


    tar 命令選項
    +-----------+---------------------------------------
    | 選 項        | 描 述
    +-----------+---------------------------------------
    | -C dir    | 切換到指定目錄
    +-----------+---------------------------------------
    | -f file    | 輸出結果到文件或設備file
    +-----------+---------------------------------------
    | -j        | 將輸出重定向給bzip2命令來壓縮內容        
    +-----------+---------------------------------------
    | -p        | 保留所有文件權限
    +-----------+---------------------------------------
    | -v        | 在處理文件時顯示文件
    +-----------+---------------------------------------
    | -z        | 將輸出重定向給gzip命令來壓縮內容
    +-----------+---------------------------------------


這些選項經常合併到一起使用。

創建一個歸檔文件:
    
    tar -cvf test.tar test/ test2/    

上面的命令創建了名爲test.tar的歸檔文件,含有test和test2目錄內容。

列出tar文件test.tar的內容:

    tar -tf test.tar

提取 test.tar 中的文件:

    tar -xvf test.tar
    
    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    下載到開源軟件之後,經常會看到文件名以 .tgz 結尾,這些是 gzip 壓縮的 tar 文件,可以用如下命令解壓:
    
    tar -zxvf filename.tgz

 

系列目錄: 

    走進 Linux shell (一)

    走進 Linux shell (二)

    走進 Linux shell (三)

 

參考:

    《Linux 命令行與 shell 腳本編程大全》 第 3 版 —— 2016.8(美)Richard Blum  Cristine Bresnahan

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