【Linux入門教程】3 程式管理、網路通訊工具、vi編輯器、檔案系統、檔案儲存結構

HelloZEX發表於2018-08-02

Linux程式管理

當我們執行程式時,Linux會為程式建立一個特殊的環境,該環境包含程式執行需要的所有資源,以保證程式能夠獨立執行,不受其他程式的干擾。這個特殊的環境就稱為程式。
每個 Linux 命令都與系統中的程式對應,輸入命令,Linux 就會建立一個新的程式。例如使用 ls 命令遍歷目錄中的檔案時,就建立了一個程式。
簡而言之,程式就是程式的例項。
系統通過一個五位數字跟蹤程式的執行狀態,這個數字稱為 pid 或程式ID。每個程式都擁有唯一的 pid。
理論上,五位數字是有限的,當數字被用完時,下一個 pid 就會重新開始,所以 pid 最終會重複。但是,兩個 pid 一樣的程式不能同時存在,因為Linux會使用 pid 來跟蹤程式的執行狀態。

建立程式

有兩種方式來建立程式:前臺程式和後臺程式。

前臺程式

預設情況下,使用者建立的程式都是前臺程式;前臺程式從鍵盤讀取資料,並把處理結果輸出到顯示器。
我們可以看到前臺程式的執行過程。例如,使用 ls 命令來遍歷當前目錄下的檔案:

$ls ch*.doc
ch01-1.doc   ch010.doc  ch02.doc    ch03-2.doc
ch04-1.doc   ch040.doc  ch05.doc    ch06-2.doc
ch01-2.doc   ch02-1.doc

這個程式就執行在前臺,它會直接把結果輸出到顯示器。如果 ls 命令需要資料(實際上不需要),那麼它會等待使用者從鍵盤輸入。
當程式執行在前臺時,由於命令提示符($)還未出現,使用者不能輸入其他命令;即使程式需要執行很長時間,也必須等待程式執行結束才能輸入其他命令。

後臺程式

後臺程式與鍵盤沒有必然的關係。當然,後臺程式也可能會等待鍵盤輸入。
後臺程式的優點是不必等待程式執行結束就可以輸入其他命令。
建立後臺程式最簡單的方式就是在命令的末尾加 &,例如:

$ls ch*.doc &
ch01-1.doc   ch010.doc  ch02.doc    ch03-2.doc
ch04-1.doc   ch040.doc  ch05.doc    ch06-2.doc
ch01-2.doc   ch02-1.doc

如果 ls 命令需要輸入(實際上不需要),那麼它會暫停,直到使用者把它調到前臺並從鍵盤輸入資料才會繼續執行。

檢視正在執行的程式

可以使用 ps 命令檢視程式的執行狀態,包括後臺程式,例如:

$ps
PID       TTY      TIME        CMD
18358     ttyp3    00:00:00    sh
18361     ttyp3    00:01:31    abiword
18789     ttyp3    00:00:00    ps

還可以結合 -f 選項檢視更多資訊,f 是 full 的縮寫,例如:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f

每列的含義如下:

描述
UID 程式所屬使用者的ID,即哪個使用者建立了該程式。
PID 程式ID。
PPID 父程式ID,建立該程式的程式稱為父程式。
C CPU使用率。
STIME 程式被建立的時間。
TTY 與程式有關的終端型別。
TIME 程式所使用的CPU時間。
CMD 建立該程式的命令。


ps 命令還有其他一些選項:

選項 說明
-a 顯示所有使用者的所有程式。
-x 顯示無終端的程式。
-u 顯示更多資訊,類似於 -f 選項。
-e 顯示所有程式。

終止程式

當程式執行在前臺時,可以通過 kill 命令或 Ctrl+C 組合鍵來結束程式。

如果程式執行在後臺,那麼首先要通過 ps 命令來獲取程式ID,然後使用 kill 命令“殺死”程式,例如:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

如上所示,kill 命令終結了 first_one 程式。

如果程式忽略 kill 命令,那麼可以通過 kill -9 來結束:

$kill -9 6738
Terminated

父程式和子程式

每個 Linux 程式會包含兩個程式ID:當前程式ID(pid)和父程式ID(ppid)。可以暫時認為所有的程式都有父程式。
由使用者執行的大部分命令都將 Shell 作為父程式,使用 ps -f 命令可以檢視當前程式ID和父程式ID。

殭屍程式和孤兒程式

正常情況下,子程式被終止時會通過 SIGCHLD 訊號通知父程式,父程式可以做一些清理工作或者重新啟動一個新的程式。但在某些情況下,父程式會在子程式之前被終止,那麼這些子程式就沒有了“父親”,被稱為孤兒程式
init 程式會成為所有孤兒程式的父程式。init 的 pid 為1,是Linux系統的第一個程式,也是所有程式的父程式。
如果一個程式被終止了,但是使用 ps 命令仍然可以檢視該程式,並且狀態為 Z,那麼這就是一個殭屍程式。殭屍程式雖然被終止了,但是仍然存在於程式列表中。一般殭屍程式很難殺掉,你可以先殺死他們的父程式,讓他們變成孤兒程式,init 程式會自動清理殭屍程式。

常駐程式

常駐程式一般是系統級程式,以 root 許可權執行在後臺,可以處理其他程式的請求。
常駐程式沒有終端,不能訪問 /dev/tty 檔案,如果使用 ps -ef 檢視該程式,tty 這一列會顯示問號(?)。
更確切地說,常駐程式通常執行在後臺,等待指定事件發生,例如列印程式是一個常駐程式,它會等待使用者輸入列印相關的命令並進行處理。

top命令

top 命令是一個很有用的工具,它可以動態顯示正在執行的程式,還可以按照指定條件對程式進行排序,與Windows的工作管理員類似。
top 命令可以顯示程式的很多資訊,包括實體記憶體、虛擬記憶體、CPU使用率、平均負載以及繁忙的程式等。例如:

$top

這裡僅給出一個示意圖,讀者最好親自執行一下:

任務和程式

任務(task)是最抽象的,是一個一般性的術語,指由軟體完成的一個活動。一個任務既可以是一個程式,也可以是多個程式。簡而言之,它指的是一系列共同達到某一目的的操作。例如,讀取資料並將資料放入記憶體中。這個任務可以由一個程式來實現,也可以由多個程式來實現。  每個任務都有一個數字表示的任務號。
程式(process)常常被定義為程式的執行。可以把一個程式看成是一個獨立的程式,在記憶體中有其完備的資料空間和程式碼空間。一個程式所擁有的資料和變數只屬於它自己。
jobs 命令可以用來檢視系統中正在執行的任務,包括後臺執行的任務。該命令可以顯示任務號及其對應的程式ID。一個任務可以對應於一個或者多個程式號。
jobs 命令的 -l 選項可以檢視當前任務包含的程式ID:

$jobs -l
[1] + 1903 running                 ls ch*.doc &
$

其中,第一列表示任務號,第二列表示任務對應的程式ID,第三列表示任務的執行狀態,第四列表示啟動任務的命令。

前臺任務和後臺任務的切換

fg 命令可以將後臺任務調到前臺,語法為:

$fg %jobnumber

jobnumber 是通過 jobs 命令獲取的後臺任務的的序號,注意不是pid。如果後臺只有一個任務,可以不指定 jobnumber。
bg 命令可以將後臺暫停的任務,調到前臺繼續執行,語法為:

$bg %jobnumber

jobnumber 同樣是通過 jobs 命令獲取的後臺任務的的序號,注意不是pid。如果前臺只有一個任務,可以不指定 jobnumber。
如果希望將當前任務轉移到後臺,可以先 Ctrl+z 暫停任務,再使用 bg 命令。任務轉移到後臺可以空出終端,繼續輸入其他命令。



Linux網路通訊工具

現在是一個網際網路的時代,你不可避免的要和其他使用者進行遠端交流,連線到遠端主機。

ping 命令

ping 命令會向網路上的主機傳送應答請求,根據響應資訊可以判斷遠端主機是否可用。

ping 命令的語法:

$ping hostname or ip-address

如果網路暢通,很快就可以看到響應資訊。

例如,檢測是否可以連線到谷歌的主機:

$ping google.com
PING google.com (74.125.67.100) 56(84) bytes of data.
64 bytes from 74.125.67.100: icmp_seq=1 ttl=54 time=39.4 ms
64 bytes from 74.125.67.100: icmp_seq=2 ttl=54 time=39.9 ms
64 bytes from 74.125.67.100: icmp_seq=3 ttl=54 time=39.3 ms
64 bytes from 74.125.67.100: icmp_seq=4 ttl=54 time=39.1 ms
64 bytes from 74.125.67.100: icmp_seq=5 ttl=54 time=38.8 ms
--- google.com ping statistics ---
22 packets transmitted, 22 received, 0% packet loss, time 21017ms
rtt min/avg/max/mdev = 38.867/39.334/39.900/0.396 ms
$

如果主機沒有響應,可以看到類似下面的資訊:

$ping giiiiiigle.com
ping: unknown host giiiiigle.com
$

ftp 工具

ftp 是 File Transfer Protocol 的縮寫,稱為檔案傳輸協議。通過 ftp 工具,能夠將檔案上傳到遠端伺服器,也可以從遠端伺服器下載檔案。

ftp 工具有自己的命令(類似Linux命令),可以:

  • 連線並登入遠端主機;
  • 檢視目錄,遍歷目錄下的檔案;
  • 上傳或下載檔案,包括文字檔案、二進位制檔案等。


ftp 命令的用法如下:

$ftp hostname or ip-address

接下來會提示你輸入使用者名稱和密碼,驗證成功後會進入主目錄,然後就可以使用 ftp 工具的命令進行操作了。
 

ftp命令 說明
put filename 將本地檔案上傳到遠端主機。
get filename 將遠端檔案下載到本地。
mput file list 將多個本地檔案上傳到遠端主機。
mget file list 將多個遠端檔案下載到本地。
prompt off 關閉提示。預設情況下,使用 mput 或 mget 命令會不斷提示你確認檔案的上傳或下載。
prompt on 開啟提示。
dir 列出遠端主機當前目錄下的所有檔案。
cd dirname 改變遠端主機目錄。
lcd dirname 改變本地目錄。
quit 退出登入。


注意,所有的上傳和下載都是針對本地主機和遠端主機的當前目錄,如果你希望上傳指定目錄下的檔案,首先要 cd 到該目錄,然後才能上傳。

ftp 工具使用舉例:

$ftp amrood.com
Connected to amrood.com.
220 amrood.com FTP server (Ver 4.9 Thu Sep 2 20:35:07 CDT 2009)
Name (amrood.com:amrood): amrood
331 Password required for amrood.
Password:
230 User amrood logged in.
ftp> dir
200 PORT command successful.
150 Opening data connection for /bin/ls.
total 1464
drwxr-sr-x   3 amrood   group       1024 Mar 11 20:04 Mail
drwxr-sr-x   2 amrood   group       1536 Mar  3 18:07 Misc
drwxr-sr-x   5 amrood   group        512 Dec  7 10:59 OldStuff
drwxr-sr-x   2 amrood   group       1024 Mar 11 15:24 bin
drwxr-sr-x   5 amrood   group       3072 Mar 13 16:10 mpl
-rw-r--r--   1 amrood   group     209671 Mar 15 10:57 myfile.out
drwxr-sr-x   3 amrood   group        512 Jan  5 13:32 public
drwxr-sr-x   3 amrood   group        512 Feb 10 10:17 pvm3
226 Transfer complete.
ftp> cd mpl
250 CWD command successful.
ftp> dir
200 PORT command successful.
150 Opening data connection for /bin/ls.
total 7320
-rw-r--r--   1 amrood   group       1630 Aug  8 1994  dboard.f
-rw-r-----   1 amrood   group       4340 Jul 17 1994  vttest.c
-rwxr-xr-x   1 amrood   group     525574 Feb 15 11:52 wave_shift
-rw-r--r--   1 amrood   group       1648 Aug  5 1994  wide.list
-rwxr-xr-x   1 amrood   group       4019 Feb 14 16:26 fix.c
226 Transfer complete.
ftp> get wave_shift
200 PORT command successful.
150 Opening data connection for wave_shift (525574 bytes).
226 Transfer complete.
528454 bytes received in 1.296 seconds (398.1 Kbytes/s)
ftp> quit
221 Goodbye.
$

telnet工具

Telnet 工具可以讓我們連線並登入到遠端計算機。

一旦連線到了遠端計算機,就可以在上面進行各種操作了,例如:

C:>telnet amrood.com
Trying...
Connected to amrood.com.
Escape character is '^]'.

login: amrood
amrood's Password:
*****************************************************
*                                                   *
*                                                   *
*            WELCOME TO AMROOD.COM                  *
*                                                   *
*                                                   *
*****************************************************

Last unsuccessful login: Fri Mar  3 12:01:09 IST 2009
Last login: Wed Mar  8 18:33:27 IST 2009 on pts/10

   {  do your work }

$ logout
Connection closed.
C:>

finger工具

finger 可以讓我們檢視本地主機或遠端主機上的使用者資訊。有些系統為了安全會禁用 finger 命令。

例如,檢視本機線上使用者:

$ finger
Login     Name       Tty      Idle  Login Time   Office
amrood               pts/0          Jun 25 08:03 (62.61.164.115)

檢視本機指定使用者的資訊:

$ finger amrood
Login: amrood                           Name: (null)
Directory: /home/amrood                 Shell: /bin/bash
On since Thu Jun 25 08:03 (MST) on pts/0 from 62.61.164.115
No mail.
No Plan.

檢視遠端主機上的線上使用者:

$ finger @avtar.com
Login     Name       Tty      Idle  Login Time   Office
amrood               pts/0          Jun 25 08:03 (62.61.164.115)

檢視遠端主機上某個使用者的資訊:

$ finger amrood@avtar.com
Login: amrood                           Name: (null)
Directory: /home/amrood                 Shell: /bin/bash
On since Thu Jun 25 08:03 (MST) on pts/0 from 62.61.164.115
No mail.
No Plan.


Linux vi編輯器

Linux下的文字編輯器有很多種,vi 是最常用的,也是各版本Linux的標配。注意,vi 僅僅是一個文字編輯器,可以給字元著色,可以自動補全,但是不像 Windows 下的 word 有排版功能。

vi 是十年磨一劍的產品,雖然命令繁多,並且大多數功能都是依靠鍵盤輸入來完成,但是一旦你熟悉後,會發現 vi 的功能和效率是其他圖形介面編輯器無法比擬的。

Vim 是 Vimproved 的縮寫,是 vi 的改進版。在Linux中,vi 被認為是事實上的標準編輯器,因為:

  • 所有版本的 Linux 都帶有 vi 編輯器;
  • 佔用資源少;
  • 與 ed、ex 等其他編輯器相比,vi 對使用者更加友好。


你可以使用 vi 編輯器編輯現有的檔案,也可以建立一個新檔案,還能以只讀模式開啟文字檔案。

進入 vi 編輯器

可以通過以下方式進入 vi 編輯器:

命令 描述
vi filename 如果filename存在,則開啟;否則會建立一個新檔案再開啟。
vi -R filename 以只讀模式(只能檢視不能編輯)開啟現有檔案。
view filename 以只讀模式開啟現有檔案。


例如,使用 vi 編輯器建立一個新檔案並開啟:

$vi testfile
|
~
~
~
~
~
~
~
~
~
~
~
~
"testfile" [New File]

豎線(|)代表游標的位置;波浪號(~)代表該行沒有任何內容。如果沒有 ~,也看不到任何內容,那說明這一行肯定是有空白字元(空格、tab 縮排、換行符等)或不可見字元。

工作模式

進一步瞭解 vi 之前先來了解一下 vi 的工作模式,vi 有三種工作模式:

1) 普通模式

由Shell進入vi編輯器時,首先進入普通模式。在普通模式下,從鍵盤輸入任何字元都被當作命令來解釋。普通模式下沒有任何提示符,輸入命令後立即執行,不需要回車,而且輸入的字元不會在螢幕上顯示出來。

普通模式下可以執行命令、儲存檔案、移動游標、貼上複製等。

2) 編輯模式

編輯模式主要用於文字的編輯。該模式下使用者輸入的任何字元都被作為檔案的內容儲存起來,並在螢幕上顯示出來。

3) 命令模式

命令模式下,使用者可以對檔案進行一些高階處理。儘管普通模式下的命令可以完成很多功能,但要執行一些如字串查詢、替換、顯示行號等操作還是必須要進入命令模式。

注意:有些教程中稱有兩種工作模式,是把命令模式合併到普通模式。

工作模式切換:

  • 在普通模式下輸入 i(插入)、c(修改)、o(另起一行) 命令時進入編輯模式;按 esc 鍵退回到普通模式。
  • 在普通模式下輸入冒號(:)可以進入命令模式。輸入完命令按回車,命令執行完後會自動退回普通模式。


提示:如果不確定當前處於哪種模式,按兩次 Esc 鍵將回到普通模式。

退出 vi 編輯器

一般在命令模式下退出 vi 編輯器。
 

退出命令 說明
q 如果檔案未被修改,會直接退回到Shell;否則提示儲存檔案。
q! 強行退出,不儲存修改內容。
wq w 命令儲存檔案,q 命令退出 vi,合起來就是儲存並退出。
ZZ 儲存並退出,相當於 wq,但是更加方便。


退出之前,你也可以在 w 命令後面指定一個檔名,將檔案另存為新檔案,例如:

w filename2

將當前檔案另存為 filename2。

注意:vi 編輯檔案時,使用者的操作都是基於緩衝區中的副本進行的。如果退出時沒有儲存到磁碟,則緩衝區中的內容就會被丟失。

移動游標

為了不影響檔案內容,必須在普通模式(按兩次 Esc 鍵)下移動游標。使用下表中的命令每次可以移動一個字元:

命令 描述
k 向上移動游標(移動一行)
j 向下移動游標(移動一行)
h 向左移動游標(移動一個字元)
l 向右移動游標(移動一個字元)


兩點提醒:

  • vi 是區分大小寫的,輸入命令時注意不要鎖定大寫。
  • 可以在命令前邊新增一個數字作為字首,例如,2j 將游標向下移動兩行。


當然,還有很多其他命令來移動游標,不過記住,一定要在普通模式(按兩次 Esc 鍵)下。
 

用來移動游標的命令
命令 說明
0 或 | 將游標定位在一行的開頭。
$ 將游標定位在一行的末尾。
w 定位到下一個單詞。
b 定位到上一個單詞。
( 定位到一句話的開頭,句子是以 ! . ? 三種符號來界定的。
) 定位到一句話的結尾。
{ 移動到段落開頭。&&&&&&
} 移動到段落結束。&&&&&&&&&
[[ 回到段落的開頭處。&&&&&&&&&&
]] 向前移到下一個段落的開頭處。&&&&&&&&&&
n| 移動到第 n 列(當前行)。
1G 移動到檔案第一行。
G 移動到檔案最後一行。
nG 移動到檔案第 n 行。
:n 移動到檔案第 n 行。
H 移動到螢幕頂部。
nH 移動到距離螢幕頂部第 n 行的位置。
M 移動到螢幕中間。
L 移動到螢幕底部。
nL 移動到距離螢幕底部第 n 行的位置。
:x x 是一個數字,表示移動到行號為 x 的行。

控制命令

有一些控制命令可以與 Ctrl 鍵組合使用,如下:

命令 描述
CTRL+d 向前滾動半屏
CTRL+f 向前滾動全屏
CTRL+u 向後滾動半屏
CTRL+b 向後滾動整屏
CTRL+e 向上滾動一行
CTRL+y 向下滾動一行
CTRL+I 重新整理螢幕

編輯檔案

切換到編輯模式下才能編輯檔案。有很多命令可以從普通模式切換到編輯模式,如下所示:

命令 描述
i 在當前游標位置之前插入文字
I 在當前行的開頭插入文字
a 在當前游標位置之後插入文字
A 在當前行的末尾插入文字
o 在當前位置下面建立一行
O 在當前位置上面建立一行

刪除字元

下面的命令,可以刪除檔案中的字元或行:

命令 說明
x 刪除當前游標下的字元
X 刪除游標前面的字元
dw 刪除從當前游標到單詞結尾的字元
d^ 刪除從當前游標到行首的字元
d$ 刪除從當前游標到行尾的字元
D 刪除從當前游標到行尾的字元
dd 刪除當前游標所在的行


可以在命令前面新增一個數字字首,表示重複操作的次數,例如,2x  表示連續兩次刪除游標下的字元,2dd 表示連續兩次刪除游標所在的行。

建議各位讀者多加練習上面的命令,再進一步深入學習。

修改文字

如果你希望對字元、單詞或行進行修改,可以使用下面的命令:

命令 描述
cc 刪除當前行,並進入編輯模式。
cw 刪除當前字(單詞),並進入編輯模式。
r 替換當前游標下的字元。
R 從當前游標開始替換字元,按 Esc 鍵退出。
s 用輸入的字元替換當前字元,並進入編輯模式。
S 用輸入的文字替換當前行,並進入編輯模式。

貼上複製

vi 中的複製貼上命令:

命令 描述
yy 複製當前行
nyy 複製n行
yw 複製一個字(單詞)
nyw 複製n行
p 將複製的文字貼上到游標後面
P 將複製的文字貼上到游標前面

高階命令

下面的一些命令雖然看起來有些古怪,但是會讓你的工作更有效率,如果你是 vi 重度使用者,就瞭解一下吧。

命令 說明
J 將當前行和下一行連線為一行
<< 將當前行左移一個單位(一個縮排寬度)
>> 將當前行右移一個單位(一個縮排寬度)
~ 改變當前字元的大小寫
^G Ctrl+G組合鍵可以顯示當前檔名和狀態
U 撤銷對當前行所做的修改
u 撤銷上次操作,再次按 'u' 恢復該次操作
:f 以百分號(%)的形式顯示當前游標在檔案中的位置、檔名和檔案的總行數
:f filename 將檔案重新命名為 filename
:w filename 儲存修改到 filename
:e filename 開啟另一個檔名為 filename 的檔案
:cd dirname 改變當前工作目錄到 dirname
:e # 在兩個開啟的檔案之間進行切換
:n 如果用 vi 開啟了多個檔案,可以使用 :n 切換到下一個檔案
:p 如果用 vi 開啟了多個檔案,可以使用 :n 切換到上一個檔案
:N 如果用 vi 開啟了多個檔案,可以使用 :n 切換到上一個檔案
:r file 讀取檔案並在當前行的後邊插入
:nr file 讀取檔案並在第 n 行後邊插入

文字查詢

如果希望進行全檔案搜尋,可以在普通模式(按兩次 Esc 鍵)下輸入 / 命令,這時狀態列(最後一行)出現"/"並提示輸入要查詢的字串,回車即可。

/ 命令是向下查詢,如果希望向上查詢,可以使用 ? 命令。

這時,輸入 n 命令可以按相同的方向繼續查詢,輸入 N 命令可以按相反的方向繼續查詢。

搜尋的字串中可以包含一些有特殊含義的字元,如果希望搜尋這些字元本身,需要在前面加反斜槓(\)。
 

部分特殊字元列表
字元 說明
^ 匹配一行的開頭
. 匹配一個字元
* 匹配0個或多個字元
$ 匹配一行的結尾
[ ] 匹配一組字元


如果希望搜尋某行中的單個字元,可以使用 f 或 F 命令,f 向上搜尋,F 向下搜尋,並且會把游標定位到匹配的字元。

也可以使用 t 或 T 命令:t 命令向上搜尋,並把游標定位到匹配字元的前面;T 命令向下搜尋,並把游標定位到匹配字元的後面。

set 命令

set 命令可以對 vi 編輯器進行一些設定。使用 set 命令需要進入命令模式。
 

:set 命令選項
命令 說明
:set ic 搜尋時忽略大小寫。
:set ai 設定自動縮排(自動對齊)。
:set noai 取消自動縮排(自動對齊)。
:set nu 顯示行號。
:set sw 設定縮排的空格數,例如,將縮排空格數設定為4::set sw=4。
:set ws 迴圈搜尋:如果直到檔案末尾也沒有查詢到指定字元,那麼會回到開頭繼續查詢。
:set wm 設定自動換行,例如,設定距離邊際2個字元時換行::set wm=2 。
:set ro 將檔案型別改為只讀。
:set term 輸出終端型別。
:set bf 忽略輸入的控制字元,如 BEL(響鈴)、BS(退格)、CR(回車)等。

執行命令

切換到命令模式,再輸入 ! 命令即可執行 Linux 命令。

例如,儲存檔案前,如果希望檢視該檔案是否存在,那麼輸入

:! ls

即可列出當前目錄下的檔案。

按任意鍵回到 vi 編輯器。

文字替換

切換到命令模式,再輸入 s/ 命令即可對文字進行替換。語法為:

:s/search/replace/g

search 為檢索的文字,replace 為要替換的文字,g 表示全域性替換。

幾點提示

vi 編輯器的使用講解完畢,但是請記住下面幾點:

  • 輸入冒號(:)進入命令模式,按兩次 Esc 鍵進入普通模式。
  • 命令大小寫的含義是不一樣的。
  • 必須在編輯模式下才能輸入內容。


Linux檔案系統

檔案系統就是分割槽或磁碟上的所有檔案的邏輯集合。

檔案系統不僅包含著檔案中的資料而且還有檔案系統的結構,所有Linux 使用者和程式看到的檔案、目錄、軟連線及檔案保護資訊等都儲存在其中。

不同Linux發行版本之間的檔案系統差別很少,主要表現在系統管理的特色工具以及軟體包管理方式的不同,檔案目錄結構基本上都是一樣的。

檔案系統有多種型別,如:

  • ext2 : 早期linux中常用的檔案系統;
  • ext3 : ext2的升級版,帶日誌功能;
  • RAMFS : 記憶體檔案系統,速度很快;
  • iso9660:光碟或光碟映象;
  • NFS : 網路檔案系統,由SUN發明,主要用於遠端檔案共享;
  • MS-DOS : MS-DOS檔案系統;
  • FAT : Windows XP 作業系統採用的檔案系統;
  • NTFS : Windows NT/XP 作業系統採用的檔案系統。

分割槽與目錄

檔案系統位於磁碟分割槽中;一個硬碟可以有多個分割槽,也可以只有一個分割槽;一個分割槽只能包含一個檔案系統。

Linux檔案系統與Windows有較大的差別。Windows的檔案結構是多個並列的樹狀結構,最頂部的是不同的磁碟(分割槽),如 C、D、E、F等。

Linux的檔案結構是單個的樹狀結構,根目錄是“/”,其他目錄都要位於根目錄下。

每次安裝系統的時候我們都會進行分割槽,Linux下磁碟分割槽和目錄的關係如下:

  • 任何一個分割槽都必須對應到某個目錄上,才能進行讀寫操作,稱為“掛載”。
  • 被掛載的目錄可以是根目錄,也可以是其他二級、三級目錄,任何目錄都可以是掛載點。
  • 目錄是邏輯上的區分。分割槽是物理上的區分。
  • 根目錄是所有Linux的檔案和目錄所在的地方,需要掛載上一個磁碟分割槽。


下圖是常見的目錄和分割槽的對應關係:


為什麼要分割槽,如何分割槽?

  • 可以把不同資料,分別放入不同分割槽中管理,降低風險。
  • 大硬碟搜尋範圍大,效率低。
  • /home、/var、/usr/local 經常是單獨分割槽,因為經常會操作,容易產生碎片。


為了便於定位和查詢,Linux中的每個目錄一般都存放特定型別的檔案,下表列出了各種Linux發行版本的常見目錄:

目錄 說明
/ 根目錄,只能包含目錄,不能包含具體檔案。
/bin 存放可執行檔案。很多命令就對應/bin目錄下的某個程式,例如 ls、cp、mkdir。/bin目錄對所有使用者有效。
/dev 硬體驅動程式。例如音效卡、磁碟驅動等,還有如 /dev/null、/dev/console、/dev/zero、/dev/full 等檔案。
/etc 主要包含系統配置檔案和使用者、使用者組配置檔案。
/lib 主要包含共享庫檔案,類似於Windows下的DLL;有時也會包含核心相關檔案。
/boot 系統啟動檔案,例如Linux核心、載入程式等。
/home 使用者工作目錄(主目錄),每個使用者都會分配一個目錄。
/mnt 臨時掛載檔案系統。這個目錄一般是用於存放掛載儲存裝置的掛載目錄的,例如掛載CD-ROM的cdrom目錄。
/proc 作業系統執行時,程式(正在執行中的程式)資訊及核心資訊(比如cpu、硬碟分割槽、記憶體資訊等)存放在這裡。/proc目錄偽裝的檔案系統proc的掛載目錄,proc並不是真正的檔案系統。
/tmp 臨時檔案目錄,系統重啟後不會被儲存。
/usr /user目下的檔案比較混雜,包含了管理命令、共享檔案、庫檔案等,可以被很多使用者使用。
/var 主要包含一些可變長度的檔案,會經常對資料進行讀寫,例如日誌檔案和列印佇列裡的檔案。
/sbin 和 /bin 類似,主要包含可執行檔案,不過一般是系統管理所需要的,不是所有使用者都需要。

常用檔案管理命令

你可以通過下面的命令來管理檔案:

Command Description
cat filename 檢視檔案內容。
cd dirname 改變所在目錄。
cp file1 file2 複製檔案或目錄。
file filename 檢視檔案型別(binary, text, etc)。
find filename dir 搜尋檔案或目錄。
head filename 顯示檔案的開頭,與tail命令相對。
less filename 檢視檔案的全部內容,可以分頁顯示,比more命令要強大。
ls dirname 遍歷目錄下的檔案或目錄。
mkdir dirname 建立目錄。
more filename 檢視檔案的全部內容,可以分頁顯示。
mv file1 file2 移動檔案或重新命名。
pwd 顯示使用者當前所在目錄。
rm filename 刪除檔案。
rmdir dirname 刪除目錄。
tail filename 顯示檔案的結尾,與head命令相對。
touch filename 檔案不存在時建立一個空檔案,存在時修改檔案時間戳。
whereis filename 檢視檔案所在位置。
which filename 如果檔案在環境變數PATH中有定義,那麼顯示檔案位置。

df命令

管理磁碟分割槽時經常會使用 df (disk free) 命令,df -k 命令可以用來檢視磁碟空間的使用情況(以千位元組計),例如:

$df -k
Filesystem      1K-blocks      Used   Available Use% Mounted on
/dev/vzfs        10485760   7836644     2649116  75% /
/devices                0         0           0   0% /devices
$

每一列的含義如下:

說明
Filesystem 代表檔案系統對應的裝置檔案的路徑名(一般是硬碟上的分割槽)。
kbytes 分割槽包含的資料塊(1024位元組)的數目。
used 已用空間。
avail 可用空間。
capacity 已用空間的百分比。
Mounted on 檔案系統掛載點。


某些目錄(例如 /devices)的 kbytes、used、avail 列為0,use列為0%,這些都是特殊(或虛擬)檔案系統,即使位於根目錄下,也不佔用硬碟空間。

你可以結合 -h (human readable) 選項將輸出資訊格式化,讓人更易閱讀。 

du 命令

du (disk usage) 命令可以用來檢視特定目錄的空間使用情況。

du 命令會顯示每個目錄所佔用資料塊。根據系統的不同,一個資料塊可能是 512 位元組或 1024 位元組。舉例如下:

$du /etc
10     /etc/cron.d
126    /etc/default
6      /etc/dfs
...
$

結合 -h 選項可以讓資訊顯示的更加清晰:

$du -h /etc
5k    /etc/cron.d
63k   /etc/default
3k    /etc/dfs
...
$

掛載檔案系統

掛載是指將一個硬體裝置(例如硬碟、U盤、光碟等)對應到一個已存在的目錄上。 若要訪問裝置中的檔案,必須將檔案掛載到一個已存在的目錄上, 然後通過訪問這個目錄來訪問儲存裝置。

這樣就為使用者提供了統一的介面,遮蔽了硬體裝置的細節。Linux將所有的硬體裝置看做檔案,對硬體裝置的操作等同於對檔案的操作。

注意:掛載目錄可以不為空,但掛載後這個目錄下以前的內容將不可用。

需要知道的是,光碟、軟盤、其他作業系統使用的檔案系統的格式與linux使用的檔案系統格式是不一樣的,掛載需要確認Linux是否支援所要掛載的檔案系統格式。

檢視當前系統所掛載的硬體裝置可以使用 mount 命令:

$ mount
/dev/vzfs on / type reiserfs (rw,usrquota,grpquota)
proc on /proc type proc (rw,nodiratime)
devpts on /dev/pts type devpts (rw)
$

一般約定,/mnt 為臨時掛載目錄,例如掛載CD-ROM、遠端網路裝置、軟盤等。

也可以通過mount命令來掛載檔案系統,語法為:

mount -t file_system_type device_to_mount directory_to_mount_to

例如:

$ mount -t iso9660 /dev/cdrom /mnt/cdrom

將 CD-ROM 掛載到 /mnt/cdrom 目錄。

注意:file_system_type用來指定檔案系統型別,通常可以不指定,Linux會自動正確選擇檔案系統型別。

掛載檔案系統後,就可以通過 cd、cat 等命令來操作對應檔案。

可以通過 umount 命令來解除安裝檔案系統。例如,解除安裝 cdrom:

$ umount /dev/cdrom

不過,大部分現代的Linux系統都有自動掛載解除安裝功能,unmount 命令較少用到。

使用者和群組配額

使用者和群組配額可以讓管理員為每個使用者或群組分配固定的磁碟空間。

管理員有兩種方式來分配磁碟空間:

  • 軟限制:如果使用者超過指定的空間,會有一個寬限期,等待使用者釋放空間。
  • 硬限制:沒有寬限期,超出指定空間立即禁止操作。


下面的命令可以用來管理配額:

命令 說明
quota 顯示磁碟使用情況以及每個使用者組的配額。
edquota 編輯使用者和群組的配額。
quotacheck 檢視檔案系統的磁碟使用情況,建立、檢查並修復配額檔案。
setquota 設定配額。
quotaon 開啟使用者或群組的配額功能。
quotaoff 關閉使用者或群組的配額功能。
repquota 列印指定檔案系統的配額。


Linux檔案儲存結構,包括目錄項、inode、資料塊

大部分的Linux檔案系統(如ext2、ext3)規定,一個檔案由目錄項、inode和資料塊組成:

  • 目錄項:包括檔名和inode節點號。
  • Inode:又稱檔案索引節點,包含檔案的基礎資訊以及資料塊的指標。
  • 資料塊:包含檔案的具體內容。

先說inode

理解inode,要從檔案儲存說起。檔案儲存在硬碟上,硬碟的最小儲存單位叫做"扇區"(Sector),每個扇區儲存512位元組(相當於0.5KB)。

作業系統讀取硬碟的時候,不會一個扇區一個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取一個"塊"(block)。這種由多個扇區組成的"塊",是檔案存取的最小單位。"塊"的大小,最常見的是4KB,即連續八個 sector組成一個 block。

檔案資料都儲存在"塊"中,那麼很顯然,我們還必須找到一個地方儲存檔案的元資訊,比如檔案的建立者、檔案的建立日期、檔案的大小等等。這種儲存檔案元資訊的區域就叫做inode,中文譯名為"索引節點"。

inode包含檔案的元資訊,具體來說有以下內容:

  • 檔案的位元組數。
  • 檔案擁有者的User ID。
  • 檔案的Group ID。
  • 檔案的讀、寫、執行許可權。
  • 檔案的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指檔案內容上一次變動的時間,atime指檔案上一次開啟的時間。
  • 連結數,即有多少檔名指向這個inode。
  • 檔案資料block的位置。


可以用stat命令,檢視某個檔案的inode資訊:

stat demo.txt

總之,除了檔名以外的所有檔案資訊,都存在inode之中。至於為什麼沒有檔名,下文會有詳細解釋。

當檢視某個檔案時,會先從inode表中查出檔案屬性及資料存放點,再從資料塊中讀取資料。

請看檔案儲存結構示意圖:

inode的大小

inode也會消耗硬碟空間,所以硬碟格式化的時候,作業系統自動將硬碟分成兩個區域。一個是資料區,存放檔案資料;另一個是inode區(inode table),存放inode所包含的資訊。

每個inode節點的大小,一般是128位元組或256位元組。inode節點的總數,在格式化時就給定,一般是每1KB或每2KB就設定一個inode。假定在一塊1GB的硬碟中,每個inode節點的大小為128位元組,每1KB就設定一個inode,那麼inode table的大小就會達到128MB,佔整塊硬碟的12.8%。

檢視每個硬碟分割槽的inode總數和已經使用的數量,可以使用df -i 命令。

檢視每個inode節點的大小,可以用如下命令:

sudo dumpe2fs -h /dev/hda | grep "Inode size"

由於每個檔案都必須有一個inode,因此有可能發生inode已經用光,但是硬碟還未存滿的情況。這時,就無法在硬碟上建立新檔案。

inode號碼

每個inode都有一個號碼,作業系統用inode號碼來識別不同的檔案。

這裡值得重複一遍,Linux系統內部不使用檔名,而使用inode號碼來識別檔案。對於系統來說,檔名只是inode號碼便於識別的別稱或者綽號。表面上,使用者通過檔名,開啟檔案。實際上,系統內部這個過程分成三步:首先,系統找到這個檔名對應的inode號碼;其次,通過inode號碼,獲取inode資訊;最後,根據inode資訊,找到檔案資料所在的block,讀出資料。

使用ls -i命令,可以看到檔名對應的inode號碼,例如:

ls -i demo.txt

目錄項

Linux系統中,目錄(directory)也是一種檔案。開啟目錄,實際上就是開啟目錄檔案。

目錄檔案的結構非常簡單,就是一系列目錄項(dirent)的列表。每個目錄項,由兩部分組成:所包含檔案的檔名,以及該檔名對應的inode號碼。

ls命令只列出目錄檔案中的所有檔名:

ls /etc

ls -i命令列出整個目錄檔案,即檔名和inode號碼:

ls -i /etc

如果要檢視檔案的詳細資訊,就必須根據inode號碼,訪問inode節點,讀取資訊。ls -l命令列出檔案的詳細資訊。

ls -l /etc

硬連結和軟連結

硬連結

一般情況下,檔名和inode號碼是"一一對應"關係,每個inode號碼對應一個檔名。但是,Linux系統允許,多個檔名指向同一個inode號碼。這意味著,可以用不同的檔名訪問同樣的內容;對檔案內容進行修改,會影響到所有檔名;但是,刪除一個檔名,不影響另一個檔名的訪問。這種情況就被稱為"硬連結"(hard link)。

ln命令可以建立硬連結,語法為:

ln source_file target_file

執行上面這條命令以後,原始檔與目標檔案的inode號碼相同,都指向同一個inode。inode資訊中有一項叫做"連結數",記錄指向該inode的檔名總數,這時就會增加1。反過來,刪除一個檔名,就會使得inode節點中的"連結數"減1。當這個值減到0,表明沒有檔名指向這個inode,系統就會回收這個inode號碼,以及其所對應block區域。

這裡順便說一下目錄檔案的"連結數"。建立目錄時,預設會生成兩個目錄項:"."和".."。前者的inode號碼就是當前目錄的inode號碼,等同於當前目錄的"硬連結";後者的inode號碼就是當前目錄的父目錄的inode號碼,等同於父目錄的"硬連結"。所以,任何一個目錄的"硬連結"總數,總是等於2加上它的子目錄總數(含隱藏目錄),這裡的2是父目錄對其的“硬連結”和當前目錄下的".硬連結“。

軟連結

除了硬連結以外,還有一種特殊情況。檔案A和檔案B的inode號碼雖然不一樣,但是檔案A的內容是檔案B的路徑。讀取檔案A時,系統會自動將訪問者導向檔案B。因此,無論開啟哪一個檔案,最終讀取的都是檔案B。這時,檔案A就稱為檔案B的"軟連結"(soft link)或者"符號連結(symbolic link)。

這意味著,檔案A依賴於檔案B而存在,如果刪除了檔案B,開啟檔案A就會報錯:"No such file or directory"。這是軟連結與硬連結最大的不同:檔案A指向檔案B的檔名,而不是檔案B的inode號碼,檔案B的inode"連結數"不會因此發生變化。

ln -s命令可以建立軟連結,語法為:

ln source_file target_file

相關文章