iT邦幫忙

2025 iThome 鐵人賽

DAY 13
3
Software Development

上班族的命令列 (CLI) 生存手冊系列 第 13

Day13 基礎操作篇:怎麼複製檔案? 以及目錄的本質

  • 分享至 

  • xImage
  •  

嗨!歡迎回到上班族的命令列生存手冊,上一個章節說明了 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

印出作業紀錄

https://ithelp.ithome.com.tw/upload/images/20250927/20141615IXHS8PYboN.png

可以用 -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(硬連結數量)嗎?就是今天了,我們即將揭曉這個是什麼東西。

硬連結 vs 軟連結

軟連結(符號連結)

上面建立的捷徑,就是一種「軟連結」,英文是:Symbolic Link / Symlink 或是 Soft Link。(所以指令才會 -s 參數)這個東西跟 Windows、Mac 或是你在圖形界面看到的捷徑有易曲同工之妙:

  • 本身只是「指向某個位置」的檔案
  • 刪掉指向的位置,會變成找不到東西的檔案,就像有些已歇業的店家,在 Google Map 上雖然找得到,但現場已經不存在一樣。

再回到 ls,還記得可以透過 $ ls -la 看到檔案詳細內容(Long Format)嗎?

https://ithelp.ithome.com.tw/upload/images/20250927/20141615LkUgnlfjK4.png

lrwxrwxrwx. 1 louis383 louis383  10  8月 13 20:59 link -> file

看到前面亂碼的部份,第一個字是 lrwxrwxrwxl 代表這個檔案是一個 Symbolic Link。
先來回味 Long format 的意思:

  • 看起來像是亂碼的東西,實際上是「權限」,也就是上面提到的那個,先看第一個字
  • 一個數字,這是 Hard Link Count (硬連結數量),正在說明這個
  • 帳號名,這是檔案的擁有者名稱
  • 另一個帳號名,這是擁有者群組名稱,別忘了 Linux 是多使用者的作業系統,可以幫各個使用者分群
  • 又一個數字,這是檔案大小,通常以位元組為單位
  • 這是修改日期和時間,檔案最後一次被修改的時間
  • 檔名,檔案或資料夾的名稱

也會注意到這個「捷徑」有 10 個位元組左右,是一個「捷徑檔案」。後面則會指出 link 這個捷徑指向 file 檔案。
那什麼是硬連結?

硬連結

如果上面的檔案用這樣的方式:

$ ln file hand_link

則會產生「硬連結」,根據上述的說明,用以下實際的例子來看看。假設有一個文字檔案,我們同時建立硬連結和軟連結。

$ ln original.txt hard_link.txt 

$ ln -s original.txt soft_link.txt

再用 $ls -la 印出 Long Format:

https://ithelp.ithome.com.tw/upload/images/20250927/20141615Qk7On1UanY.png

會注意到不管是 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 .. 時可以回到上層目錄的原因,而軟連結本質上是紀錄指向另外一個檔案的「檔案」所以也有自己的 inodehard_link.txtoriginal.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 格式,就完全不支援這些功能。

給 Nerd 專用表格

特性 硬連結 (Hard Link) 軟連結 (Symbolic Link/Soft Link)
inode 與目標檔案共用同一個 inode 擁有自己獨立的 inode
本質 另一個指向 inode 的檔名 一個儲存目標路徑的特殊檔案
跨檔案系統
連結目錄
刪除原始檔 只要連結計數 > 0,資料依然存在 連結會失效
ls -l 顯示 連結計數會增加 指出 link -> target

上一篇
Day12 基礎操作篇:灑上快樂魔法 — Shell 的 Framework
下一篇
Day14 基礎操作篇:怎麼移動檔案? — 說說 mv
系列文
上班族的命令列 (CLI) 生存手冊15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
chiaominchang222
iT邦新手 5 級 ‧ 2025-09-27 11:25:39

太早起啦

我要留言

立即登入留言