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選項
選項 | 含義 |
-i,--interactive | 覆蓋一個已存在的文件之前,提示用 戶確認。如果沒有指定該選項,mv會默認覆蓋文件 |
-u,--update | 將文件從一個目錄移動到另一個目錄, 只移動那些目標目錄中不存在的文件或 是目標目錄裏相應文件的更新文件 |
-v,--verbose | 移動文件時顯示信息性消息 |
表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選項
選項 | 含義 |
-i,--interactive | 刪除一個已存在的文件前,提示用戶確認。 如果沒有指定這個選項,rm命令會默認刪除文件 |
-r,--recursive | 遞歸地刪除目錄。也就是說,如果刪除 的目錄有子目錄的話,也要將其刪除。要刪 除一個目錄,則必須指定該選項 |
-f,--force | 忽略不存在的文件並無需提示確認。 該選項會覆蓋--interactive選項 |
-v,--verbose | 刪除文件時顯示信息性消息 |
表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命令是個例外。當刪除一個鏈接的時候,鏈接本身被刪除,但是目標文件依舊存在。
最後,我們需要刪除目錄playground。爲此,我們將返回主目錄,使用rm命令的遞歸選項(-r)來刪除playground目錄以及包括子目錄在內的所有內容。
1.[me@linuxbox playground]$ cd
2.[me@linuxbox ~]$ rm -r playground
使用GUI創建符號鏈接
GNOME和KDE中的文件管理器提供了一種自動創建符號鏈接的簡單方法。在GNOME環境下,拖拽文件時同時按住Ctrl-Shift鍵將會新建鏈接文件,而不是執行復制(移動)操作。在KDE環境下,無論什麼時候放下(drop)一個文件都會彈出一個小菜單,它提供了複製、移動或創建鏈接文件等選項。