本篇介紹如何在 Linux 系統下使用 cp
指令複製檔案或目錄,並提供常見的使用範例。
在 Linux 系統之中若要進行檔案或目錄的複製,可以使用 cp
指令,而除了簡單的複製檔案之外,此指令也具有額外的建立連結、自動備份等附加功能,以下是 cp
指令的使用方式介紹。
若要將 source.txt
檔案複製一份到 dest.txt
,可以執行:
# 將 source.txt 複製到 dest.txt
cp source.txt dest.txt
若要將 source.txt
複製到其他目錄之下,可以指定絕對路徑:
# 將 source.txt 複製到 /path/to/dest.txt
cp source.txt /path/to/dest.txt
如果要將檔案複製到其他目錄,保持原來的檔案名稱,可以僅指定目的目錄即可,也就是說以下兩種寫法是等效的:
# 將 source.txt 複製到 /path/to/source.txt cp source.txt /path/to/source.txt # 將 source.txt 複製到 /path/to/source.txt cp source.txt /path/to/
亦可將多個檔案一起複製到目的目錄:
# 將 source1.txt、source2.txt、source3.txt 複製到 /path/to 目錄中
cp source1.txt source2.txt source3.txt /path/to/
如果要複製整個目錄以及該目錄下的所有子目錄與檔案,可以加上 -r
參數(或是 -R
、--recursive
參數亦可),以遞迴的方式進行複製:
# 將 myfolder 目錄複製到 /path/to/ 路徑下 cp -r myfolder /path/to/
若遇到目的檔案已存在的情況,cp
指令預設會覆蓋既有的檔案內容,但是如果目的檔案檔案無法寫入(例如檔案權限設定為唯讀),就會無法進行複製的動作。
如果希望 cp
指令在無法寫入目的檔案時,嘗試刪除目的檔案,再重新複製一份新的檔案,可以加上 -f
或 --force
參數:
# 強制複製檔案 cp -f source.txt dest.txt
如果希望 cp
指令在每次複製檔案前都先刪除目的檔案,再進行檔案的複製,則可加上 --remove-destination
參數:
# 先刪除目的檔案,再進行複製 cp --remove-destination source.txt dest.txt
如果希望 cp
指令遇到目的檔案已經存在的狀況,不要覆蓋既有的檔案,可以加上 -n
或 --no-clobber
參數:
# 不要覆蓋既有檔案 cp -n source.txt dest.txt
另一種方式是加上 -i
或 --interactive
參數,讓 cp
在覆蓋檔案之前,先詢問使用者,經確認之後再進行覆寫:
# 經確認後再覆寫檔案 cp -i source.txt dest.txt
若希望 cp
指令在覆蓋檔案時,可以將舊檔案自動備份起來,可以加上 -b
或 --backup
參數:
# 自動備份檔案 cp -b source.txt dest.txt
cp
指令預設會將原始檔案名稱加上 ~
這個後綴,作為備份檔案名稱(例如 dest.txt
就會備份至 dest.txt~
),若要自行指定備份檔名後綴,可以用 -S
或 --suffix
參數來更改,例如改用 .bak
作為備份檔案名稱的後綴:
# 指定備份檔名後綴 cp -b -S .bak source.txt dest.txt
這樣 dest.txt
就會被備份至 dest.txt.bak
。
若希望 cp
在複製檔案時,可以連同檔案屬性一起複製,可以加上 -p
或 --preserve
參數:
# 保留檔案屬性 cp -p source.txt dest.txt
加上 -p
或 --preserve
參數預設會保留權限(mode
)、擁有者(ownership
)、時間戳記(timestamps
),若希望更改保留的屬性種類,可以使用 --preserve
參數來指定,其餘可用的選項有 SELinux contexts(context
)、連結(links
)、延伸屬性(xattr
)、所有屬性(all
),例如:
# 指定保留的檔案屬性 cp --preserve=mode,ownership,timestamps,xattr source.txt dest.txt
若只要複製檔案的屬性,而不要複製檔案本身的資料,可以加上 --attributes-only
參數:
# 只複製檔案屬性 cp --attributes-only source.txt dest.txt
關於各屬性種類的說明,可以參考 File permissions and attributes。
假設我們建立一個連結檔 link.txt
指向 source.txt
:
# 建立連結檔 ln -s source.txt link.txt
如果希望 cp
指令在複製連結檔案時,能夠解析連結檔所指向的實際檔案,複製那一個實際的目標檔案,可以加上 -L
或 --dereference
參數:
# 複製檔案(解析連結) cp -L link.txt dest.txt
由於 link.txt
是指向 source.txt
的連結檔,所以這裡的 dest.txt
實際上就是從 source.txt
所複製出來了。
若希望 cp
指令在複製連結檔案時,不要進行連結的解析,僅將連結檔直接複製,則可改用 -P
或 --no-dereference
參數:
# 複製檔案(保留連結) cp -P link.txt link2.txt
此處所複製出來的 link2.txt
就僅僅是一個指向 source.txt
的連結檔案。
cp
指令若加上 -s
或 --symbolic-link
參數,可以用軟連結(symbolic link)的方式建立檔案,也就是等同於使用 ln -s
指令來建立連結:
# 以軟連結複製檔案 cp -s source.txt link.txt
這樣建立的 link.txt
檔案就是一個指向 source.txt
的連結檔。
若要以硬連結複製檔案,可以加上 -l
或 --link
參數:
# 以硬連結複製檔案 cp -l source.txt dest.txt
這裡 dest.txt
的 inode 會與 source.txt
相同。
若要保留來源檔案的目錄結構,可以加上 --parents
參數:
# 保留來源目錄結構 cp --parents path/to/source.txt myfolder/
這樣就會把 path/to/source.txt
複製到 myfolder/path/to/source.txt
。
cp
指令若加上 -u
或 --update
參數,就會自動檢查來源檔案與目的檔案的修改時間,如果來源檔案比目的檔案更新,才會更新目的檔案,否則就不做任何動作:
# 僅更新檔案 cp -u source.txt dest.txt