本篇介紹如何在 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