Linux常用命令-cp

命令

cp

描述

copy files and directories
复制文件或目录

用法

1
2
3
cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Options:
-a 归档模式,等同于-dR --preserve=all
-b 如果目标文件存在则先备份目标文件,默认名称为文件名加~符号,如file~
-S SUFFIX 指定备份文件的后缀,配合-b选项
-d 等同于-P --preserve=links
-f 强制覆盖
-i 覆盖文件之前提示
-l 创建硬链接文件
-s 创建软链接文件
-L 如果源文件是软链接则复制原文件而非软链接文件(默认选项)
-P 如果源文件是软链接则复制软链接文件而非原文件
-n 不覆盖已存在的文件,如果目标文件已存在则跳过
-p 等同于--preserve=mode,ownership,timestamps
-R, -r 递归复制
-u 更新文件,即当源文件比较新或者目标文件不存在时复制文件
-v 显示详情
--preserve[=ATTR_LIST] 保留指定属性(默认:mode,ownership,timestamps,可添加属性:context, links, xattr,all)
--no-preserve=ATTR_LIST 不保留指定属性,值同上说明

注意

文件到文件的复制: 目标文件不存在则新建;目标文件存在则提示/覆盖/更新
文件到目录的复制: 源文件可以指定多个,但是目标目录只能指定一个且必须存在
目录到目录的复制: 两个目录之间复制,目标目录不存在则新建,存在则将源目录作为子目录复制到目标目录下;多个目录复制,源可以指定多个目录,最后一个目录为目标目录,所有目录必须存在.

复制目录下的所有文件但不包括隐藏文件cp -a dir1/* dir2/
复制目录下的所有文件包括隐藏文件cp -a dir1/. dir2/
只复制目录下的隐藏文件cp -a dir1/.[^.]* dir2/

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
$ ls
a dir1/
# 默认cp命令是别名,添加了-i选项
$ alias cp
alias cp='cp -i'
$ cp a b
$ cp -f a b
cp: overwrite ‘b’? y
# 因为cp命令别名定义了-i选项,所以即使加-f也会有提示,要使用原始命令可以加\cp转义或者使用命令绝对路径/usr/bin/cp
$ \cp -f a b
$ /usr/bin/cp -f a b
$ cp -a a c
$ cp a dir1/d
# 默认目标文件为当前时间,加-a选项则保留原文件的一切属性包括时间
$ ll
-rw-r--r-- 1 root root 4 Jan 14 22:13 a
-rw-r--r-- 1 root root 4 Jan 14 22:17 b
-rw-r--r-- 1 root root 4 Jan 14 22:13 c
drwxr-xr-x 2 root root 15 Jan 14 22:17 dir1/
$ ll dir1/d
-rw-r--r-- 1 root root 4 Jan 14 22:17 dir1/d

# -b选项覆盖目标文件前先备份,默认文件名加~,-S指定文件名后缀如下.bak
$ cp -b a b
$ cp -b -S '.bak' a c
$ ls
a b b~ c c.bak dir1/
# 也可以通过如下命令来创建一个.bak的备份文件,即文件名{,.bak},后缀可自定义
$ cp a{,.bak}
$ ls a*
a a.bak

# 复制软链接文件,默认是复制链接的原文件,加-d选项则相当于创建一个新的软链接,加-a选项则同样保留所有属性
$ ln -s a aaa
$ cp aaa bbb
$ cp -d aaa ccc
$ cp -a aaa ddd
$ ll
-rw-r--r-- 1 root root 4 Jan 14 22:13 a
lrwxrwxrwx 1 root root 1 Jan 14 22:27 aaa -> a
-rw-r--r-- 1 root root 4 Jan 14 22:27 bbb
lrwxrwxrwx 1 root root 1 Jan 14 22:28 ccc -> a
lrwxrwxrwx 1 root root 1 Jan 14 22:27 ddd -> a

# 通过cp命令创建链接文件,-l硬链接,-s软链接
$ echo aaa > file
$ cp -l file file1
$ cp -s file file2
# 如下所示,file和file1的inode号码一致,即为硬链接
$ ll -i file*
33648472 -rw-r--r-- 2 root root 4 Jan 14 22:40 file
33648472 -rw-r--r-- 2 root root 4 Jan 14 22:40 file1
33648473 lrwxrwxrwx 1 root root 4 Jan 14 22:40 file2 -> file

$ echo aaa > a
$ echo bbb > b
$ ls
a b b~ c c.bak
# -n选项目标文件已存在则跳过
$ cp -n a b
$ more b
bbb
# -p选项同步复制源文件的所有者和时间戳属性
$ cp -p a b
$ more b
aaa
$ ll a b
-rw-r--r-- 1 root root 4 Jan 14 22:47 a
-rw-r--r-- 1 root root 4 Jan 14 22:47 b
# -u选项只有在源文件比较新时才会复制,以下是b文件比a文件时间要新,所以不会复制
$ echo bbb > b
$ cp -u a b
$ more b
bbb
$ ll a b
-rw-r--r-- 1 root root 4 Jan 14 22:47 a
-rw-r--r-- 1 root root 4 Jan 14 22:49 b
# 更新a文件的时间戳,然后重新复制
$ touch a
$ cp -v a b
‘a’ -> ‘b’
$ more b
aaa

# -r选项递归复制目录,-a选项也可以直接复制目录并保留属性
$ cp dir1 dir2
cp: omitting directory ‘dir1’
$ cp -r dir1 dir2
$ cp -a dir1 dir3
$ ll -d dir*/
drwxr-xr-x 2 root root 97 Jan 14 22:46 dir1/
drwxr-xr-x 2 root root 97 Jan 14 22:51 dir2/
drwxr-xr-x 2 root root 97 Jan 14 22:46 dir3/
# cp支持同时复制多个源文件或目录到一个已存在的目标目录.即源可以有多个,但目标只能有一个且必须为目录
$ cp -r a b c dir1 dir2
$ cp a b c d
cp: target ‘d’ is not a directory
$ cp a b c dir22
cp: target ‘dir22’ is not a directory

# 复制目录中的隐藏文件,一级目录和二级目录下均有隐藏文件的情况需要注意,说明如下
$ mkdir dir1
$ echo aaa > dir1/a1
$ echo 123 > dir1/.a
$ mkdir dir1/sdir1
$ echo bbb > dir1/sdir1/a2
$ echo 123 > dir1/sdir1/.b
$ tree -al dir1/
dir1/
├── .a
├── a1
└── sdir1
├── a2
└── .b
1 directory, 4 files
# 目标目录dir2不存在,则直接复制会自动创建dir2目录,且和dir1的目录结构完全一致
$ cp -a dir1/ dir2
$ tree -al dir2
dir2
├── .a
├── a1
└── sdir1
├── a2
└── .b
1 directory, 4 files
# 目标目录dir3已存在,则直接复制会将dir1作为子目录复制到dir3目录中
$ mkdir dir3
$ cp -a dir1/ dir3/
$ ll dir3
drwxr-xr-x 3 root root 39 Jan 14 23:33 dir1/
$ tree -al dir3
dir3
└── dir1
├── .a
├── a1
└── sdir1
├── a2
└── .b
2 directories, 4 files
$ rm -rf dir3/*
# 如果源指定为dir1/*,则会复制dir1目录下的所有子文件和子目录,除了一级目录下的隐藏文件或隐藏目录,如上的.a文件.(子目录下的隐藏文件不受影响)
$ cp -a dir1/* dir3/
$ ll dir3/
-rw-r--r-- 1 root root 4 Jan 14 23:32 a1
drwxr-xr-x 2 root root 26 Jan 14 23:33 sdir1/
$ tree -al dir3/
dir3/
├── a1
└── sdir1
├── a2
└── .b
1 directory, 3 files
# 要想复制一级目录下的隐藏文件,需要指定源为dir1/.[^.]*,(即以.开头的,不包括..的所有隐藏文件或目录)
$ mkdir dir1/.sdir1
$ cp dir1/.[^.]* dir3/
$ tree -al dir3/
dir3/
├── .a
├── a1
├── sdir1
│   ├── a2
│   └── .b
└── .sdir1
# 同时复制目录下的所有文件包括隐藏文件,直接指定dir1/.即可
$ cp -a dir1/. dir3/