cp:複制檔案和目錄。
mv:移動或重命名檔案和目錄。
mkdir:建立目錄。
rm:移除檔案和目錄。
in:建立硬連結和符号連結。
這5個指令屬于最常使用的Linux指令之列,可用來操作檔案與目錄。
坦率地說,使用圖形檔案管理器來執行一些由這些指令執行的任務要容易得多。使用檔案管理器,我們可以将檔案從一個目錄拖放到另一個目錄,我們可以剪切和粘貼檔案,我們可以删除檔案。那麼,為什麼還要用這些指令行程式呢?
原因就在于指令行程式具有強大的功能和靈活的操作。雖然使用圖形檔案管理器能輕松實作簡單的檔案操作,但是對于複雜的任務,使用指令行程式更容易完成。例如,怎樣僅因為檔案在目标目錄中不存在或存在舊的版本,就将所有HTML檔案從一個目錄複制到目标目錄裡呢?要完成這個任務,使用檔案管理器則相當困難,而使用指令行則很容易。
1.cp -u *.html destination
4.1 通配符
在開始使用指令之前,我們需要介紹一個使指令行如此強大的shell特性。由于shell需要經常使用檔案名,是以它提供了一些特殊字元來幫助你快速指定一組檔案名。這些特殊字元稱為通配符。通配符(也叫檔案名替換)允許使用者依據字元模式選擇檔案名。表4-1列出了通配符以及它們所選擇的對象。
表4-1 通配符
通配符 | 比對項 |
* | 比對任意多個字元(包括0個和1個) |
? | 比對任一單個字元(不包括0個) |
[characters] | 比對任意一個屬于字元集中的字元 |
[!characters] | 比對任意一個不屬于字元集中的字元 |
[[:class:]] | 比對任意一個屬于指定字元類中的字元 |
表4-2列出了最常用的字元類。
表4-2 常用的字元類
字元類 | |
[:alnum:] | 比對任意一個字母或數字 |
[:alpha:] | 比對任意一個字母 |
[:digit] | 比對任意一個數字 |
[:lower:] | 比對任意一個小寫字母 |
[:upper:] | 比對任意一個大寫字母 |
通配符的使用使得為檔案名建構複雜的篩選标準成為可能。表 4-3 列出了一些通配符模式及其比對内容的示例。
表4-3 通配符示例
模式 | |
所有檔案 |
續表
形式 | |
g* | 以g開頭的任一檔案 |
b*.txt | 以b開頭,中間有任意多個字元, 并以.txt結尾的任一檔案 |
Data??? | 以Data開頭,後面跟3個字元的任一檔案 |
[abc]* | 以abc中的任一個開頭的任一檔案 |
BACKUP.[0-9][0-9][0-9] | 以BACKUP.開頭,後面緊跟3個數字的任一檔案 |
[[:upper:]]* | 以大寫字母開頭的任一檔案 |
[![:digit:]]* | 不以數字開頭的任一檔案 |
*[[:lower:]123] | 以小寫字母或數字1、2、3中 的任一個結尾的任一檔案 |
通配符可以與任一個使用檔案名為參數的指令一起使用,在第7章我們會進一步讨論。
字元範圍
如果你之前使用過其他的類UNIX環境或是讀過該主題的相關書籍,可能遇到過[A-Z]或[a-z]形式的字元範圍表示法。這些都是傳統的UNIX表示法,在早期的Linux版本中仍然奏效。盡管它們仍然起作用,但使用時請務必小心,因為一旦配置不當,就會産生非預期的結果。目前,我們要避免使用它們,而是使用字元類。
通配符在GUI中也奏效
通配符相當有用,不僅僅因為它們在指令行中使用頻繁,而且在于一些圖形檔案管理器也支援通配符操作。
在Nautilus(GNOME的檔案管理器)中,你可以使用Edit->Select Pattern選擇檔案。僅僅輸入一個用通配符表示的檔案選擇模式後,則目前檢視的目錄中,所比對的檔案就會突出顯示。
在Dolphin和Konqueror(KDE的檔案管理器)的一些版本中,你可以直接在位址欄輸入通配符。比如,如果想要在/usr/bin目錄中查找所有以小寫字元u開始的檔案,隻需在位址欄輸入/usr/bin/u*,即可顯示比對的結果。
最初源于指令行界面的許多理念,也同樣适用于圖形界面。而這恰恰是使Linux系統桌面如此強大的原因之一。
4.2 mkdir-建立目錄
mkdir指令是用來建立目錄的,格式如下。
1.mkdir directory…
注意表示法:本書在描述指令時,如果參數後面帶有3個點号(如上所示),這表示該參數重複。是以,下面這種情況:
1.mkdir dir1
可建立單個dir1目錄,而輸入:
1.mkdir dir1 dir2 dir3
可建立3個目錄,分别命名為dir1、dir2和dir3。
4.3 cp-複制檔案和目錄
cp指令用來複制檔案和目錄。它有兩種不同的使用方式,如下所示。
1.cp item1 item2
将單個檔案或目錄item1複制到檔案或目錄item2中。
1.cp item… directory
将多個項目(檔案或目錄)複制進一個目錄中。
表4-4和表4-5列出了cp常用的選項(短選項和等價的長選項)。
表4-4 cp指令選項
選項 | 含義 |
-a,--archive | 複制檔案和目錄及其屬性,包括所有 權和權限。通常來說,複制的檔案具 有使用者所操作檔案的預設屬性 |
-i,--interactive | 在覆寫一個已存在的檔案前,提示使用者 進行确認。如果沒有指定該選項,cp 會預設覆寫檔案 |
-r,--recursive | 遞歸地複制目錄及其内容。複制目錄時 需要這個選項(或-a選項) |
-u,--update | 當将檔案從一個目錄複制到另一個目 錄時,隻會複制那些目标目錄中不存在 的檔案或是目标目錄相應檔案的更新檔案 |
-v,--verbose | 複制檔案時,顯示資訊性消息 (informative message) |
表4-5 cp指令示例
指令 | 結果 |
cp file1 file2 | 将file1複制到file2。如果file2存在, 則會被file1的内容覆寫。如果file2不存在,則建立file2 |
cp –i file1 file2 | 同上,差別在于當file2存在時,覆寫之 前通知使用者确認 |
cp file1 file2 dir1 | 将file1和file2複制到目錄dir1裡。dir1必須已經存在 |
cp dir1/* dir2 | 通過使用通配符,将dir1中的所有檔案複 制的dir2中。dir2必須已經存在 |
cp –r dir1 dir2 | 将dir1目錄(及其内容)複制到dir2目錄 中。如果dir2不存在,建立dir2,且包含 與dir1目錄相同的内容 |
4.4 mv-移除和重命名檔案
mv指令可以執行檔案移動和檔案重命名操作,這具體取決于如何使用它。在這兩種情況下,完成操作之後,原來的檔案名将不存在。mv的使用方法與cp基本相似。
1.mv item1 item2
将檔案(或目錄)item1移動(或重命名)為item2,或是
1.mv item… directory
将一個或多個條目從一個目錄移動到另一個目錄下。
mv指令很多選項與cp指令是共享的,如表4-6和表4-7所示。
表4-6 mv選項
覆寫一個已存在的檔案之前,提示用 戶确認。如果沒有指定該選項,mv會預設覆寫檔案 | |
将檔案從一個目錄移動到另一個目錄, 隻移動那些目标目錄中不存在的檔案或 是目标目錄裡相應檔案的更新檔案 | |
移動檔案時顯示資訊性消息 |
表4-7 mv示例
mv file1 file2 | 将file1移到file2。如果file2存在,則會 被file1的内容覆寫。如果file2不存在, 則建立file2。無論哪一種情況,file1不再存在 |
mv –i file1 file2 | 同上,僅當file2存在時,覆寫之前通知使用者确認 |
mv file1 file2 dir1 | 将file1和file2移到目錄dir1下。dir1必 須已經存在 |
mv dir1 dir2 | 将目錄dir1(和其内容)移到目錄dir2下。 如果目錄dir2不存在,建立目錄dir2,将目 錄dir1的内容移到dir2下,同時删除目錄dir1 |
4.5 rm-删除檔案和目錄
rm指令用來移除(删除)檔案和目錄,如下所示。
1.rm item…
其中,item是一個或多個檔案(或目錄)的名稱。
小心rm指令
類UNIX作業系統(如Linux)并不包含還原删除操作的指令。一旦使用rm指令,就徹底地删除了。Linux系統預設使用者是明智的,并清楚自己在幹什麼。
rm指令與通配符在一起使用時要特别小心。來看下面這個經典的示例。假設我們隻希望删除目錄中的HTML檔案,為此需要輸入以下正确的指令:
1.rm *.html
如果不小心在*與.html之間多打了一個空格,如下所示:
1.rm * .html
rm 指令将會删除目錄中所有檔案,并提示說明目錄中沒有叫做.html 的檔案。
提示:當rm指令與通配符一起使用時,除仔細檢查輸入内容外,可使用ls指令預先對通配符做出測試,這将顯示欲删除的檔案。緊接着,你可以按下向上方向鍵調用之前的指令,并使用rm代替ls。
表4-8和表4-9列出了rm指令的一些常用選項。
表4-8 rm選項
删除一個已存在的檔案前,提示使用者确認。 如果沒有指定這個選項,rm指令會預設删除檔案 | |
遞歸地删除目錄。也就是說,如果删除 的目錄有子目錄的話,也要将其删除。要删 除一個目錄,則必須指定該選項 | |
-f,--force | 忽略不存在的檔案并無需提示确認。 該選項會覆寫--interactive選項 |
删除檔案時顯示資訊性消息 |
表4-9 rm執行個體
rm file1 | 在不提示使用者的情況下,删除file1 |
rm –i file1 | 删除file1前,提示使用者确認 |
rm –r file1 dir1 | 删除file1、dir1以及它們的内容 |
rm –rf file1 dir1 | 同上,當時在file1或dir1不存在時, rm仍會繼續執行,且不提示使用者 |
4.6 ln--建立連結
ln指令可用來建立硬連結或是符号連結。它的使用方式有兩種。
1.ln file link
用來建立硬連結,而
1.ln -s item link
用來建立符号連結,這裡的item可以是檔案也可以是目錄。
4.6.1 硬連結
硬連結是最初UNIX用來建立連結的方式,符号連結較之更為先進。預設情況下,每個檔案有一個硬連結,該硬連結會給檔案起名字。當建立一個硬連結的時候,也為這個檔案建立了一個額外的目錄條目。硬連結有兩條重要的局限性。
硬連結不能引用自身檔案系統之外的檔案。也就是說,連結不能引用與該連結不在同一磁盤分區的檔案。
硬連結無法引用目錄。
硬連結和檔案本身沒有什麼差別。與包含符号連結的目錄清單不同,包含硬連結的目錄清單沒有特别的連結訓示說明。當硬連結被删除時,隻是删除了這個連結,但是檔案本身的内容依然存在(也就是說,該空間沒有釋放),除非該檔案的所有連結都被删除了。
因為會經常遇到它們,了解硬連結就顯得特别重要。但是現在大多使用的是符号連結,下面将會有所介紹。
4.6.2 符号連結
符号連結是為了克服硬連結的局限性而建立的。符号連結是通過建立一個特殊類型的檔案來起作用的,該檔案包含了指向引用檔案或目錄的文本指針。就這點來看,符号連結與Windows系統下的快捷方式非常相似,但是,符号連結要早于Windows的快捷方式很多年。
符号連結指向的檔案與符号連結自身幾乎沒有差別。例如,将一些東西寫進符号連結裡,那麼這些東西同樣也寫進了引用檔案。而當删除一個符号連結時,删除的隻是符号連結而沒有删除檔案本身。如果先于符号連結之前删除檔案,那麼這個連結依然存在,但卻不指向任何檔案。此時,這個連結就稱為壞連結。在很多實作中,ls指令會用不同的顔色來顯示壞連結,比如紅色,進而顯示它們的存在。
連結的概念似乎很令人迷惑,但是不要害怕。我們要經常性地使用,它們慢慢的就會清晰起來。
4.7 實戰演練
由于我們要做一些實際的檔案操作,我們先來建立一個安全的地帶,來執行檔案操作指令。首先,我們需要一個工作目錄。我們在主目錄裡建立一個目錄并命名為playground。
4.7.1 建立目錄
mkdir指令用來建立一個目錄。為了建立playground目錄,我們首先要保證目前目錄是主目錄,然後再建立新目錄。
1.[me@linuxbox ~]$ cd
2.[me@linuxbox ~]$ mkdir playground
3.
為了讓我們的實戰演練更有意思,我們在playground目錄中建立兩個目錄,命名為dir1、dir2。為此,我們應先将目前的工作目錄切換為playground,然後再次執行mkdir指令。
1.[me@linuxbox ~]$ cd playground
2.[me@linuxbox playground]$ mkdir dir1 dir2
需要注意的是,mkdir指令可以接受多個參數,進而允許我們用一個指令建立兩個目錄。
4.7.2 複制檔案
接下來,讓我們在建立的目錄中放入一些資料。這一過程可通過檔案複制來完成。通過使用cp指令,我們可以将/ect目錄中的passwd檔案複制到目前工作目錄裡。
1.[me@linuxbox playground]$ cp /etc/passwd .
注意我們是如何使用目前工作目錄的快捷方式的,即在指令末尾加單個句點。如果我們此時執行ls指令,将會看到我們的檔案。
1.[me@linuxbox playground]$ ls -l
2.total 12
3.drwxrwxr-x 2 me me 4096 2012-01-10 16:40 dir1
4.drwxrwxr-x 2 me me 4096 2012-01-10 16:40 dir2
5.-rw-r--r-- 1 me me 1650 2012-01-10 16:07 passwd
現在讓我們使用-v選項,重複操作複制指令,來看看結果如何。
1.[me@linuxbox playground]$ cp -v /etc/passwd .
2.'/etc/passwd' -> './passwd'
cp指令再次執行複制操作,但是,這一次顯示了一條簡潔的資訊來指明它正在執行什麼操作。需要注意的是,在沒有任何警告的情況下,cp指令覆寫了第一次的複制内容。cp指令會假定使用者清楚自己目前的操作。加上-i(互動式)選項可以獲得警告資訊。
1.[me@linuxbox playground]$ cp -i /etc/passwd .
2.cp: overwrite './passwd'?
通過在提示符下輸入y,檔案就會被重寫;任何其他的字元(比如,n)會使cp指令保留該檔案。
4.7.3 移動和重命名檔案
現在,passwd這個名字似乎沒有那麼有趣,而我們畢竟是在進行實戰演練,是以我們給它改個名字。
1.[me@linuxbox playground]$ mv passwd fun
現在傳送fun檔案,這是通過将重命名的檔案移動到各個目錄,然後再移動回目前目錄來實作的:
1.[me@linuxbox playground]$ mv fun dir1
首先移到目錄dir1下,然後:
1.[me@linuxbox playground]$ mv dir1/fun dir2
将檔案從目錄dir1移到dir2,然後:
1.[me@linuxbox playground]$ mv dir2/fun .
再将檔案fun重新移到目前工作目錄下。下面來看mv指令的效果。首先,再次将資料檔案移到目錄dir1。
1.[me@linuxbox playground]$ mv fun dir1
然後将目錄dir1移到dir2并且使用ls指令進行确認。
1.[me@linuxbox playground]$ mv dir1 dir2
2.[me@linuxbox playground]$ ls -l dir2
3.total 4
4.drwxrwxr-x 2 me me 4096 2012-01-11 06:06 dir1
5.[me@linuxbox playground]$ ls -l dir2/dir1
6.total 4
7.-rw-r--r-- 1 me me 1650 2012-01-10 16:33 fun
注意,因為目錄dir2已經存在,mv指令将目錄dir1移到dir2。如果dir2不存在,mv将dir1重命名為dir2。最後,我們将所有東西放回原處。
1.[me@linuxbox playground]$ mv dir2/dir1 .
2.[me@linuxbox playground]$ mv dir1/fun .
4.7.4 建立硬連結
現在,我們試着建立一些連結。首先是建立硬連結,我們先按照如下方式建立一些指向資料檔案的連結:
1.[me@linuxbox playground]$ ln fun fun-hard
2.[me@linuxbox playground]$ ln fun dir1/fun-hard
3.[me@linuxbox playground]$ ln fun dir2/fun-hard
目前有4個檔案fun的執行個體。來看一下playground目錄。
1.[me@linuxbox playground]$ ls -l
2.total 16
3.drwxrwxr-x 2 me me 4096 2012-01-14 16:17 dir1
4.drwxrwxr-x 2 me me 4096 2012-01-14 16:17 dir2
5.-rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun
6.-rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun-hard
可以注意到,在清單中,檔案fun和fun-hard的第二個字段都是4,這是檔案fun存在的硬連結數目。你要記得,由于檔案名是由連結建立的,是以一個檔案通常至少有一個連結。那麼,我們是如何知道fun和fun-hard實際上是同一個檔案的呢?這種情況下,ls指令無濟于事。雖然從第5個字段得知fun和fun-hard檔案大小相同,但是我們的清單并沒有提供可靠的方式來确認它們是否是同一個檔案。要解決這個問題,必須做進一步研究。
提到硬連結時,可以想象檔案是由兩部分組成的,即包含檔案内容的資料部分和包含檔案名的名稱部分。建立硬連結時,實際上是建立了額外的名稱,這些名稱都指向同一資料部分。系統配置設定了一系列的盤塊給所謂的索引節點(inode),該節點随後與檔案名稱部分建立關聯。是以,每個硬連結都指向包含檔案内容的具體索引節點。
ls指令有一種方式可以顯示上述資訊。它是通過在指令中加上-i選項來實作的。
1.[me@linuxbox playground]$ ls -li
2.total 16
3.12353539 drwxrwxr-x 2 me me 4096 2012-01-14 16:17 dir1
4.12353540 drwxrwxr-x 2 me me 4096 2012-01-14 16:17 dir2
5.12353538 -rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun
6.12353538 -rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun-hard
在這個清單中,第一個字段就是索引節點号,可以看到,fun和fun-hard共享同一個索引節點号,這就證明它們是相同的檔案。
4.7.5 建立符号連結
隻是以建立符号連結,是為了克服硬連結的兩大不足,即硬連結無法跨越實體裝置,也無法引用目錄,隻能引用檔案。符号連結是一種特殊類型的檔案,它包含了指向目标檔案或目錄的文本指針。
建立符号連結與建立硬連結相似,如下所示。
1.[me@linuxbox playground]$ ln -s fun fun-sym
2.[me@linuxbox playground]$ ln -s ../fun dir1/fun-sym
3.[me@linuxbox playground]$ ln -s ../fun dir2/fun-sym
第一個指令相當直接,我們隻是在ln指令中添加-s選項,就可以建立符号連結而不是硬連結。但是,接下來的兩個指令是幹什麼的呢?牢記一點,建立符号連結時,同時也建立一個文本來描述目标檔案在哪裡與與符号連結有關聯。如果看看ls指令的輸出就更容易明白了。
1.[me@linuxbox playground]$ ls -l dir1
2.total 4
3.-rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun-hard
4.lrwxrwxrwx 1 me me 6 2012-01-15 15:17 fun-sym -> ../fun
在目錄dir1中,fun-sym的清單顯示它是一個符号連結,這是通過第1個字段中的首字元"l"來确認的,并且它也指"../fun",這也是正确的。相對于fun-sym的實際位置,檔案fun在它的上一級目錄。還要注意到,符号連結檔案的長度是6,這是"../fun"字元串中字元的數目,而不是它所指向的檔案的長度。
建立符号連結時,可以使用絕對路徑名,如下所示:
1.[me@linuxbox playground]$ ln -s /home/me/playground/fun dir1/fun-sym
也可以使用相對路徑,如前面的示例所示。因為相對路徑允許包含符号連結的目錄被重命名和/或移動,而且不會破壞連結,是以更可取一些。
除了普通檔案之外,符号連結也可以引用目錄。
1.[me@linuxbox playground]$ ln -s dir1 dir1-sym
2.[me@linuxbox playground]$ ls -l
3.total 16
4.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir1
5.lrwxrwxrwx 1 me me 4 2012-01-16 14:45 dir1-sym -> dir1
6.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir2
7.-rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun
8.-rw-r--r-- 4 me me 1650 2012-01-10 16:33 fun-hard
9.lrwxrwxrwx 1 me me 3 2012-01-15 15:15 fun-sym -> fun
4.7.6 移除檔案和目錄
前面講到,使用rm指令可以删除檔案和目錄。那麼我們就用它來清空playground目錄。首先,我們删除目錄中的一個硬連結。
1.[me@linuxbox playground]$ rm fun-hard
2.[me@linuxbox playground]$ ls -l
3.total 12
4.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir1
5.lrwxrwxrwx 1 me me 4 2012-01-16 14:45 dir1-sym -> dir1
6.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir2
7.-rw-r--r-- 3 me me 1650 2012-01-10 16:33 fun
8.lrwxrwxrwx 1 me me 3 2012-01-15 15:15 fun-sym -> fun
不出所料,檔案file-hard被删除了,檔案fun的連結數相應的也由4變成了3,如目錄清單的第二個字段所示。接下來,我們删除檔案fun,為了好玩,我們還會加上-i選項,看看執行了哪些操作。
1.[me@linuxbox playground]$ rm -i fun
2.rm: remove regular file 'fun'?
在提示符下輸入字元y,檔案就被删除了。現在看一下ls指令的輸出。注意fin-sym檔案發生了什麼變化?由于它是一個符号連結,且指向的檔案現在已經不存在,是以連結也就破壞了。
1.[me@linuxbox playground]$ ls -l
2.total 8
3.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir1
4.lrwxrwxrwx 1 me me 4 2012-01-16 14:45 dir1-sym -> dir1
5.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir2
6.lrwxrwxrwx 1 me me 3 2012-01-15 15:15 fun-sym -> fun
大多數Linux發行版會配置ls指令,來顯示破壞的連結。在Fedora系統中,破壞的連結是以閃爍的紅色來顯示的!受破壞的連結并不危險,但是會相當混亂麻煩。如果試圖調用破壞的連結,将會看到如下情況:
1.[me@linuxbox playground]$ less fun-sym
2.fun-sym: No such file or directory
稍微清理一下。我們準備删除符号連結。
1.[me@linuxbox playground]$ rm fun-sym dir1-sym
2.[me@linuxbox playground]$ ls -l
3.total 8
4.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir1
5.drwxrwxr-x 2 me me 4096 2012-01-15 15:17 dir2
有關符号連結,需要記住一點,即大部分檔案操作是以連結目标為對象的,而非連結本身。而rm指令是個例外。當删除一個連結的時候,連結本身被删除,但是目标檔案依舊存在。
1.[me@linuxbox playground]$ cd
2.[me@linuxbox ~]$ rm -r playground
GNOME和KDE中的檔案管理器提供了一種自動建立符号連結的簡單方法。在GNOME環境下,拖拽檔案時同時按住Ctrl-Shift鍵将會建立連結檔案,而不是執行複制(移動)操作。在KDE環境下,無論什麼時候放下(drop)一個檔案都會彈出一個小菜單,它提供了複制、移動或建立連結檔案等選項。