嗨!歡迎回到上班族的命令列生存手冊,上一個章節說明了 Framework,這一個章節又回到的操作的環節。有些在熟悉環境篇漏掉的操作,比如說「複製」。怎麼在終端機裡頭複製一個檔案呢?在命令列之中,我們用的指令是 cp
。
$ cp <路徑> <其他路徑>
複製一個檔案,只需要使用:
$ cp file1 file2
就可以複製 file1,新的檔案名子是 file2。需要注意的是,如果 file2 早就存在,則會直接被覆蓋過去!
如果 file2 的位置是一個資料夾則會複製一份 file1 到這個資料夾。 例如:
$ cp file1 download
file1 就會被複製一份到 download 資料夾。那怎麼複製一個資料夾呢?很簡單,只需要加上 -r
指令即可。
r 的意思是 recursive 也就是指遞迴。
$ cp download download02
就會複製 download 資料夾(包含下面的東西)成 download02 資料夾。不過,這時候如果 download02 本來就存在,則會複製 download 資料夾至 download02 底下。也就是說 download02 會多一個 download 資料夾(和原來裡面的內容)。
有的時候太早起床,複製東西一沒注意就覆蓋到原來的檔案,這時候怎麼辦?可以謹慎一點加上 -i
進入互動模式(interactive mode),如果遇到已經存在的檔案,就會請你確認是否真的要複製囉。
$ cp -i download download02
可以用 -v
來印出執行的內容。-v
指令也能接在 -r
指令的後面 -rv
,複製資料夾時就能一併的看到執行內容啦!
cp 指令支援使用 * 號來選擇某種檔案名稱作為 Pattern,如果有類似的名子用這招很方便。打個比方,例如目錄下有這些檔案:
xaa xab xac xad xae
一個一個複製很麻煩,不過可以看得出來都是 xa 開頭,這時就可以這樣子下指令:
$ cp xa* newfolder
就能一次把 xa 開頭的檔案,一次複製到 newfolder 之下。
一樣用上面的範例,讀者可以想像更混亂的情況。比如說,只想要複製 xaa,xac,xae 三個檔案到 newfolder。這時候可以用 -t
指令。拆解如下:$ cp -t <目標資料夾> <檔案...>
用我們的範例來說就是:
$ cp -t newfolder xaa xac xae
別忘記這類的可以存取到檔案、資料夾的指令,本質上都是路徑。所以可以大膽的去下指令,裡如將上一層資料夾的內容,複製到現在資料夾下的其他資料夾:
$ cp ../hello.mp3 anotherFolder/newFolder
上面的指令是將上一層(如果你不太明白 ..
請看熟悉環境篇介紹 cd
的文章)的 mp3 音樂,複製到現在資料夾下的 anotherFolder 資料夾裡面的 newFolder 資料夾。
在 Windows 裡很常用的一個功能是捷徑(macOS 之中叫「替身」),可以放在其他地方快速的開啟某個檔案或資料夾。在命令列之中,也可以建立捷徑,能在其他地方建立後,指向原來的檔案或資料夾。
建立捷徑的方式是
$ ln -s file link
上面指令會建立名為 link 的捷徑,他指向 file 檔案。還記得我們在介紹 ls
時提到一個東西— Hard Link Count(硬連結數量)嗎?就是今天了,我們即將揭曉這個是什麼東西。
上面建立的捷徑,就是一種「軟連結」,英文是:Symbolic Link / Symlink 或是 Soft Link。(所以指令才會 -s
參數)這個東西跟 Windows、Mac 或是你在圖形界面看到的捷徑有易曲同工之妙:
再回到 ls
,還記得可以透過 $ ls -la
看到檔案詳細內容(Long Format)嗎?
lrwxrwxrwx. 1 louis383 louis383 10 8月 13 20:59 link -> file
看到前面亂碼的部份,第一個字是 lrwxrwxrwx
, l
代表這個檔案是一個 Symbolic Link。
先來回味 Long format 的意思:
也會注意到這個「捷徑」有 10 個位元組左右,是一個「捷徑檔案」。後面則會指出 link 這個捷徑指向 file 檔案。
那什麼是硬連結?
如果上面的檔案用這樣的方式:
$ ln file hand_link
則會產生「硬連結」,根據上述的說明,用以下實際的例子來看看。假設有一個文字檔案,我們同時建立硬連結和軟連結。
$ ln original.txt hard_link.txt
$ ln -s original.txt soft_link.txt
再用 $ls -la
印出 Long Format:
會注意到不管是 original.txt 還是 hard_link.txt ,Hard Link Count 都變成 2,到底這個數字代表啥?
說到這個,就必須說明什麼是 inode,電腦把檔案紀錄到硬碟裡頭,硬碟會被切割成像是現在公寓大樓一樣,不同的房間入住不同的人,不過我們能知道誰住哪一間?哪一個大戶擁有一層之中的好幾間?那些套房是他的?他們又是什麼時候買的?這時,如果社區有一本住戶的資料,就很容易可以回答上述問題。
而 inode 就是硬碟的住戶資料,用來存檔案們的 metadata。有些檔案很苗條,只需要幾個區塊就能放好。有些檔案很大,分別放在不同的區塊。inode 可以指明這些檔案在哪裡,每個檔案的 Hard Link Count 等於 1 代表有一個檔案擁有某一個 inode。
硬連結產生出來的檔案,會和原檔案「共用同一個 inode」,基本上他們就是同一個檔案!如果刪除其中一個,只要還有其他人也用這個 inode,檔案就不會真的被刪除,Hard Link Count 代表有多少檔案共用了某一 inode。
白話一點說就是 Hebe 和田馥甄是同一個人(想不到吧?),但有很多不同的名子。
最後,資料夾是沒辦法建立硬連結的。
阿,沒想到已經是這個時間了,那… 下一章節會來討論怎麼移動檔案,怎麼在命令列做呢?我們下個章節見囉。
好的各位,為了滿足求知慾,這裡補充更多的軟硬連結相關的知識,首先來介紹「目錄」也就是資料夾到底是什麼?
在 POSIX 系統之中萬物皆檔案,目錄也不利外。上面提到的 inode 裡頭紀錄了檔案真正的位置,也就是住戶真正住的地方。目錄本質一個檔案,就是住戶名冊本身。裡頭的資訊是「檔案名稱」並對應到一個 inode。大概會是這個樣子的:
檔案名稱 | inode 編號 (這邊都是舉例,也就是我隨意編造的號碼) |
---|---|
. |
131182 (指向此目錄自己的 Inode) |
.. |
131072 (指向上層目錄的 Inode) |
hard_link.txt |
131205 |
original.txt |
131205 |
soft_link.txt |
131190 |
這也是為何在 $ cd ..
時可以回到上層目錄的原因,而軟連結本質上是紀錄指向另外一個檔案的「檔案」所以也有自己的 inode,hard_link.txt
和 original.txt
互為硬連結,所以指向的 inode 是同一個。
在 Windows 之中,可以把一個硬碟切割成許多的分區,或是每加入一個新的硬碟,自成一個新分區。所以常常有 C:\
槽 D:\
槽…等等。雖然 POSIX 系統沒有 C:\ D:\
槽的觀念,但一樣可以把一個硬碟切個很多個分割區,或是每個硬碟都是自己的一區。
還記得在 Windows,硬碟檔案系統通常會是 NTFS。在 POSIX 系統之中,Linux 常見的是 ext4 或 btrfs 格式,macOS 則是 APFS。POSIX 系統的硬碟系統才有 inode,雖然 NTFS 有類似的設計,那個是微軟自己的版本,這裡我們以 POSIX 系統的設計為主。
一本住戶資料,是綁在檔案系統之中的。不同的分割區就像不同的大樓,不能把社區 A 的住戶資訊指向社區 B 的住戶資訊說是同一個,因為就是不同一群人住的(先不要考慮買很多房的老王 = =),檔案也是一樣。硬連結,不能跨越分割區,不能跨越不同的檔案系統。
但是軟連結可以,上面提到其本身只是「指向某個位置」的檔案,有自己的 inode 不需要共用。
由上所知,檔案系統必須支援硬連結(有 inode) 與軟連結(檔案系統定義一種特殊的檔案,讓作業系統在讀取它時知道要去進行「重新導向」)功能,這些都是檔案系統默默的處理的。
換句話說,沒有實作相關功能的話,就完全無法用囉。就像小時候(蛤?)用的 Windows 95/98/Me 系統用的 FAT32 格式,就完全不支援這些功能。
特性 | 硬連結 (Hard Link) | 軟連結 (Symbolic Link/Soft Link) |
---|---|---|
inode | 與目標檔案共用同一個 inode | 擁有自己獨立的 inode |
本質 | 另一個指向 inode 的檔名 | 一個儲存目標路徑的特殊檔案 |
跨檔案系統 | 否 | 是 |
連結目錄 | 否 | 是 |
刪除原始檔 | 只要連結計數 > 0,資料依然存在 | 連結會失效 |
ls -l 顯示 |
連結計數會增加 | 指出 link -> target |