1. 程式人生 > >每天一個linux命令:拷貝命令家族(cp、scp、rsync) --- cp

每天一個linux命令:拷貝命令家族(cp、scp、rsync) --- cp

每天一個linux命令:拷貝命令家族(cp、scp、rsync) — cp

1. cp功能

cp 命令用來將一個或多個原始檔或者目錄複製到目標檔案或目錄。

更多精彩請檢視:www.zicreate.com

2.命令格式

cp [選項]… [-T] 源 目的
或:cp [選項]… 源… 目錄
或:cp [選項]… -t 目錄 源…

3.主要命令引數

-a:此引數的效果和同時指定”-dpR”引數相同;
-d:當複製符號連線時,把目標檔案或目錄也建立為符號連線,並指向與原始檔或目錄連線的原始檔案或目錄;
-f:強行復制檔案或目錄,不論目標檔案或目錄是否已存在;
-i:覆蓋既有檔案之前先詢問使用者;
-l:對原始檔建立硬連線,而非複製檔案;
-p:保留原始檔或目錄的屬性;
-R/r:遞迴處理,將指定目錄下的所有檔案與子目錄一併處理;
-s:對原始檔建立符號連線,而非複製檔案;
-u:使用這項引數後只會在原始檔的更改時間較目標檔案更新時或是名稱相互對應的目標檔案並不存在時,才複製檔案;
-S:在備份檔案時,用指定的字尾“SUFFIX”代替檔案的預設字尾;
-b:覆蓋已存在的檔案目標前將目標檔案備份;
-v:詳細顯示命令執行的操作。

4.使用場景

場景1:檔案備份

命令:

備份檔案到檔案:

$ cp zicreate.txt bak_zicreate.txt

注意:如果不加“-i”引數拷貝,不論bak_zicreate.txt是否存在,命令執行時都不會提示,這種情況下,如果我們拷貝過程中不想覆蓋已經存在的同名檔案,可以新增“-i”引數。大部分系統中已經對cp命令進行過處理,拷貝時會提示是否覆蓋,如下:

$ cp joke.txt bak_joke.txt
    cp: overwrite ‘bak_joke.txt’? y
$ which cp
alias cp='cp -i'
        /usr/bin/cp

如果覺得每次輸入y太繁瑣,可以直接取消別名:

$ unaslias cp (這只是臨時取消cp的別名)

或者用如下方法同樣是取消別名:

$ \cp joke.txt bak_joke.txt

再或者輸入:

$ yes | cp joke.txt bak_joke.txt,使用管道自動輸入yes。

或備份到指定目錄下:

$ cp zicreate.txt ./bak-dir/

或將整個目錄備份到指定目錄下:

$ cp -r dir1 dir3

注意:如果dir3目錄不存在,則會建立目錄dir3,如果dir3目錄存在,則會將資料夾dir1拷貝到目錄dir3裡面。

$ cp -r dir1 dir3
$ ls
dir1  dir2  dir3  joke.txt  onlyOne.txt  test.txt zicreate.txt
$ ls dir3/
test1.txt
$ cp -r dir1 dir3
$ ls dir3/
dir1  test1.txt

場景2:拷貝時儲存原始檔的所有許可權

這種情況主要應用與拷貝程式可執行程式安裝包、檔案系統目錄等特殊場景。

命令:

$cp -rp rootfs/ /mnt/sdcard/

-p引數,可以保持許可權、宿主、時間棧,還可能包括link等;還有更簡單的,就是用:

$cp -a rootfs/ /mnt/sdcard/

-a引數,就等於-dpR。

前文的資料夾拷貝都是將資料夾整個拷貝到另一個資料夾內,如果是將資料夾內的全部或部分檔案拷貝到已經存在的目標資料夾內,則一般使用萬用字元,如“*”進行目錄內容拷貝。

$ ls -a ./dir1
.  ..  .canotsee.txt  test1.txt
$ rm dir3/* -rf
$ ls dir3/ -a
.  ..
$ cp dir1/* dir3/ -rf
$ ls dir3/ -a
.  ..  test1.txt

發現沒?使用萬用字元 “*” 拷貝時,隱藏檔案“.canotsee.txt ” 沒有被拷貝到目標資料夾內!
原因是:“*” 萬用字元定義問題,解決方法很簡單,用“.” 代替“*”就好了(在Linux中,“.” 代表當前目錄,“..” 代表上級目錄)。
最終的完全拷貝命令如下:

$ cp dir1/. dir3/ -rf

關於Shell 萬用字元的解釋將會推出後續文章,此處只需要記住, ”*” 代表任意字串,但是位於首字母位置的“.”除外!