cp命令用來複制文件或者目錄,是Linux系統中最經常使用的命令之一。通常狀況下,shell會設置一個別名,在命令行下複製文件時,若是目標文件已經存在,就會詢問是否覆蓋,無論你是否使用-i參數。可是若是是在shell腳本中執行cp時,沒有-i參數時不會詢問是否覆蓋。這說明命令行和shell腳本的執行方式有些不一樣。 node
cp [選項]... [-T] 源 目的shell
或:cp [選項]... 源... 目錄安全
或:cp [選項]... -t 目錄 源...服務器
將源文件複製至目標文件,或將多個源文件複製至目標目錄。ssh
-a, --archive 等於-dR --preserve=all,--backup[=CONTROL 爲每一個已存在的目標文件建立備份spa
-b 相似--backup 但不接受參數--copy-contents 在遞歸處理是複製特殊文件內容命令行
-d 等於--no-dereference --preserve=linksdebug
-f, --force 若是目標文件沒法打開則將其移除並重試(當 -n 選項 存在時則不需再選此項)3d
-i, --interactive 覆蓋前詢問(使前面的 -n 選項失效)代理
-H 跟隨源文件中的命令行符號連接
-l, --link 連接文件而不復制
-L, --dereference 老是跟隨符號連接
-n, --no-clobber 不要覆蓋已存在的文件(使前面的 -i 選項失效)
-P, --no-dereference 不跟隨源文件中的符號連接
-p 等於--preserve=模式,全部權,時間戳, --preserve[=屬性列表 保持指定的屬性(默認:模式,全部權,時間戳),若是 可能保持附加屬性:環境、連接、xattr 等
-R, -r, --recursive 複製目錄及目錄內的全部項目
scp是基於ssh的安全拷貝命令(security copy),它是從古老的遠程複製命令rcp改變而來,實現的是在host與host之間的拷貝,能夠是本地到遠程的、本地到本地的,甚至能夠遠程到遠程複製。注意,scp可能會詢問密碼。
若是scp拷貝的源文件在目標位置上已經存在時(文件同名),scp會替換已存在目標文件中的內容,但保持其inode號。
若是scp拷貝的源文件在目標位置上不存在,則會在目標位置上建立一個空文件,而後將源文件中的內容填充進去。
scp拷貝本質是隻是填充內容的過程,它不會去修改目標文件的不少屬性。
scp [-12BCpqrv] [-l limit] [-o ssh_option] [-P port] [[user@]host1:]file1 ... [[user@]host2:]file2
選項說明:
-1:使用ssh v1版本,這是默認使用協議版本
-2:使用ssh v2版本
-C:拷貝時先壓縮,節省帶寬
-l limit:限制拷貝速度,Kbit/s.
-o ssh_option:指定ssh鏈接時的特殊選項,通常用不上。偶爾在鏈接過程當中等待提示輸入密碼較慢時,能夠設置GSSAPIAuthentication爲no
-P port:指定目標主機上ssh端口,大寫的字母P,默認是22端口
-p:拷貝時保持源文件的mtime,atime,owner,group,privileges
-r:遞歸拷貝,用於拷貝目錄。注意,scp拷貝遇到連接文件時,會拷貝連接的源文件內容填充到目標文件中(scp的本質就是填充而非拷貝)
-v:輸出詳細信息,能夠用來調試或查看scp的詳細過程,分析scp的機制
1.把本地文件/home/a.tar.tz拷貝到遠程服務器192.168.0.7上的/home/tmp,鏈接時使用遠程的root用戶:
scp /home/a.tar.tz root@192.168.0.7:/home/tmp/
2.目標主機不寫路徑時,表示拷貝到對方的家目錄下:
scp /home/a.tar.tz root@192.168.0.7
3.把遠程文件/home/a.tar.gz拷貝到本機:
scp root@192.168.0.7:/home/a.tar.tz # 不接本地目錄表示拷貝到當前目錄
scp root@192.168.0.7:/home/a.tar.tz /tmp # 拷貝到本地/tmp目錄下
4.拷貝遠程機器的/home/目錄到本地/tmp目錄下。
scp -r root@192.168.0.7:/home/ /tmp
5.從遠程主機192.168.10.8拷貝文件到另外一臺遠程主機192.168.10.9上。
scp root@192.168.10.8:/tmp/copy.txt root@192.168.10.9:/tmp
在遠程複製到遠程的過程當中,例如在本地執行scp命令將A主機(192.168.10.8)上的/tmp/copy.txt複製到B主機(192.168.10.9)上的/tmp目錄下,若是使用-v選項查看調試信息的話,會發現它的步驟相似是這樣的。
# 如下是從結果中提取的過程 # 首先輸出本地要執行的命令 Executing: /usr/bin/ssh -v -x -oClearAllForwardings yes -t -l root 192.168.10.8 scp -v /tmp/copy.txt root@192.168.10.9:/tmp # 從本地鏈接到A主機 debug1: Connecting to 192.168.10.8 [192.168.10.8] port 22. debug1: Connection established. # 要求驗證本地和A主機之間的鏈接 debug1: Next authentication method: password root@192.168.10.8's password: # 將scp命令行修改後發送到A主機上 debug1: Sending command: scp -v /tmp/copy.txt root@192.168.10.9:/tmp # 在A主機上執行scp命令 Executing: program /usr/bin/ssh host 192.168.10.9, user root, command scp -v -t /tmp # 驗證A主機和B主機之間的鏈接 debug1: Next authentication method: password root@192.168.100.62's password: # 從A主機上拷貝源文件到最終的B主機上 debug1: Sending command: scp -v -t /tmp Sending file modes: C0770 24 copy.txt Sink: C0770 24 copy.txt copy.txt 100% 24 0.0KB/s # 關閉本地主機和A主機的鏈接 Connection to 192.168.10.8 closed.
也就是說,遠程主機A到遠程主機B的複製,其實是將scp命令行從本地傳遞到主機A上,由A本身去執行scp命令。也就是說,本地主機不會和主機B有任何交互行爲,本地主機就像是一個代理執行者樣,只是幫助傳送scp命令行以及幫助顯示信息。
其實從本地主機和主機A上的~/.ssh/know_hosts文件中能夠看出,本地主機只是添加了主機A的信息,並無添加主機B的信息,而在主機A上則添加了主機B的信息。