关于cp命令中拷贝所有的写法

今天在编写一个脚本的时候,发现一个比较奇怪的问题:就是在使用cp拷贝当前目录下所有文件到目标目录的时候,源和目标目录大小不同。原来一直没有留意有这样的问题,后来查了些资料,才知道以前一直使用的格式有误,
一、预备
cp就是拷贝,最简单的使用方式就是:

cp oldfile newfile

但这样只能拷贝文件,不能拷贝目录,所以通常用:

cp -r old/ new/

那就会把old目录整个拷贝到new目录下。注意,不是把old目录里面的文件拷贝到new目录,而是把old直接拷贝到new下面,结果是:

引用

[[email protected] test]# ll new/
total
4
drwxr-xr-x  2 root root 4096 Dec 15 11:55 old

那如果要保持源文件的所有权限,可以这样:

cp -rp old/ new/

-p参数,可以保持权限、宿主、时间栈,还可能包括link等;还有更简单的,就是用:

cp -a old/new/

-a参数,就等于-dpR。
二、问题1
好,我们来看看这次的问题。环境是:
◎两个目录:old、new,其中old里面有个三个内容:test1文件、test2目录,还有就是.test3,这是一个隐含文件。

引用

[[email protected] test]# ll -laR
.:
total
20
drwxr-xr-x  4 root root 4096 Dec 15 11:55 .
drwxrwxrwt
 7 root root 4096 Dec 15 11:59 ..
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 new
drwxr-xr-x  3 root root 4096 Dec
15 12:14 old

./new:
total 8
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 .
drwxr-xr-x  4 root root 4096 Dec 15
11:55 ..

./old:
total 12
drwxr-xr-x  3 root root
4096 Dec 15 12:14 .
drwxr-xr-x  4 root root 4096 Dec 15
11:55 ..
-rw-r--r--  1 root root    0 Dec 15 12:07
.test3
-rw-r--r--  1 root root    0 Dec 15 12:05
test1
drwxr-xr-x  2 root root 4096 Dec 15 12:14
test2

./old/test2:
total 8
drwxr-xr-x  2 root root
4096 Dec 15 12:14 .
drwxr-xr-x  3 root root 4096 Dec 15
12:14 ..

◎操作一:

引用

[[email protected] test]# cp -a old/*
new/
[[email protected] test]# ll -laR new/
new/:
total
12
drwxr-xr-x  3 root root 4096 Dec 15 12:15 .
drwxr-xr-x
 4 root root 4096 Dec 15 11:55 ..
-rw-r--r--  1 root
root    0 Dec 15 12:05 test1
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 test2

new/test2:
total
8
drwxr-xr-x  2 root root 4096 Dec 15 12:14 .
drwxr-xr-x
 3 root root 4096 Dec 15 12:15 ..

问题出来了:隐含的.test3文件没有一齐拷贝到new目录下。
原因是:*参数使用不正确。这样的写法,通常都是因为熟悉了过去Dos的格式(包括我自己),而实际在bash环境下,cp使用*是不能匹配类似.开头的隐含文件的。
◎操作二
正确的写法应该这样:

引用

[[email protected] test]# cp -a old/.
new/
[[email protected] test]# ll -laR new/
new/:
total
12
drwxr-xr-x  3 root root 4096 Dec 15 12:14 .
drwxr-xr-x
 4 root root 4096 Dec 15 11:55 ..
-rw-r--r--  1 root
root    0 Dec 15 12:07 .test3
-rw-r--r--  1 root
root    0 Dec 15 12:05 test1
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 test2

new/test2:
total
8
drwxr-xr-x  2 root root 4096 Dec 15 12:14 .
drwxr-xr-x
 3 root root 4096 Dec 15 12:14 ..

不用*号,而用.号代替。
还有一种比较复杂一些的写法:

引用

[[email protected] test]# cp -a old/* old/.[^.]*
new/
[[email protected] test]# ll -laR new/
new/:
total
12
drwxr-xr-x  3 root root 4096 Dec 15 12:25 .
drwxr-xr-x
 4 root root 4096 Dec 15 11:55 ..
-rw-r--r--  1 root
root    0 Dec 15 12:07 .test3
-rw-r--r--  1 root
root    0 Dec 15 12:05 test1
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 test2

new/test2:
total
8
drwxr-xr-x  2 root root 4096 Dec 15 12:14 .
drwxr-xr-x
 3 root root 4096 Dec 15 12:25 ..

请注意写法,不要写成.*了。(原因请看下面)
三、问题2
上面提到不要写成.*,那.*代表什么?

引用

[[email protected] test]# echo .*
.
..

.*代表的是当前目录,以及上一层目录。
所以,使用.*会导致更大的问题:

引用

[[email protected] test]# cp -a old/.* new/
cp:
cannot copy a directory, `old/..‘, into itself, `new/‘
cp: cannot
copy a directory, `old/..‘, into itself, `new/‘
cp: will not
create hard link `new/old‘ to directory `new/.‘
cp: overwrite
`new/.test3‘? y
[[email protected] test]# ll -laR new/
new/:
total
16
drwxr-xr-x  4 root root 4096 Dec 15 11:55 .
drwxr-xr-x
 4 root root 4096 Dec 15 11:55 ..
-rw-r--r--  1 root
root    0 Dec 15 12:07 .test3
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 new
-rw-r--r--  1 root root  
 0 Dec 15 12:05 test1
drwxr-xr-x  2 root root 4096 Dec
15 12:14 test2

new/new:
total 8
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 .
drwxr-xr-x  4 root root 4096 Dec 15
11:55 ..
-rw-r--r--  1 root root    0 Dec 15 12:07
.test3
-rw-r--r--  1 root root    0 Dec 15 12:05
test1

new/test2:
total 8
drwxr-xr-x  2 root root
4096 Dec 15 12:14 .
drwxr-xr-x  4 root root 4096 Dec 15
11:55 ..

也就是说,使用.*就等于这样了:

引用

[[email protected] test]# cp -a old/. old/..
old/.test3 new/
[[email protected] test]# echo old/.*
old/. old/..
old/.test3

四、扩展

其实这样的问题,不单cp命令有这样的问题,在所有涉及含有特殊字符意义文件的命令时,都需要考虑,例如rm:

引用

[[email protected] new]# ll -a
total
12
drwxr-xr-x  3 root root 4096 Dec 15 12:14 .
drwxr-xr-x
 4 root root 4096 Dec 15 11:55 ..
-rw-r--r--  1 root
root    0 Dec 15 12:07 .test3
-rw-r--r--  1 root
root    0 Dec 15 12:05 test1
drwxr-xr-x  2 root
root 4096 Dec 15 12:14 test2
[[email protected] new]# rm -rf
*
[[email protected] new]# ll -a
total 8
drwxr-xr-x  2 root
root 4096 Dec 15 12:40 .
drwxr-xr-x  4 root root 4096 Dec 15
11:55 ..
-rw-r--r--  1 root root    0 Dec 15 12:07
.test3

正确的写法应该是:

引用

[[email protected] new]# rm -rf .* *
rm: cannot
remove `.‘ or `..‘
rm: cannot remove `.‘ or `..‘
[[email protected]
new]# ll -a
total 8
drwxr-xr-x  2 root root 4096 Dec 15
12:42 .
drwxr-xr-x  4 root root 4096 Dec 15 11:55
..

当然,这是一样的:

引用

[[email protected] new]# rm -rf *
.[^.]*
[[email protected] new]# ll -a
total 8
drwxr-xr-x  2
root root 4096 Dec 15 12:44 .
drwxr-xr-x  4 root root 4096
Dec 15 11:55 ..

※很多时候,预计的和实际的结果是完全不一样的。bash编写脚本尤其需要注意。

时间: 2024-08-28 08:00:32

关于cp命令中拷贝所有的写法的相关文章

【翻译自mos文章】 asmcmd cp命令不能拷贝大于2GB的文件。

asmcmd cp命令不能拷贝大于2GB的文件. 参考原文: Asmcmd CP Command Can Not Copy Files Larger Than 2 GB (Doc ID 786258.1) 适用于: Oracle Server - Enterprise Edition - Version: 11.1.0.7 This problem can occur on any platform. Oracle Server Enterprise Edition - Version: 11.

mv与cp命令

cp命令与mv命令在很多功能上都非常的相似,但是这两个命令又具有着很大的区别,其中最明显的区别也是使用中需要注意的就是cp命令的使用会保留源文件与目录,而mv命令的使用会将源文件与目录删除. 如果希望复制文件,可以直接使用命令 cp 源文件 目的文件 来完成,命令输入后系统会在当前目录下复制,如果目的文件名存在则内容被重写,如果目的文件名不存在系统将会创建.如果希望剪切文件或者是重命名文件可以使用命令 mv 源文件 目的文件,命令输入后当前目录下会出现与源文件内容相同但名称不同的新文件,并且源文

linux下拷贝命令中的文件过滤操作记录

在日常的运维工作中,经常会涉及到在拷贝某个目录时要排查其中的某些文件.废话不多说,下面对这一需求的操作做一记录: linux系统中,假设要想将目录A中的文件复制到目录B中,并且复制时过滤掉源目录A中的文件a和b做法如下:#cd A#cp -r `ls |grep -v a |grep -v b| xargs` B注意:1)上面在cp命令执行前,最好提前cd切换到源目录A下,不然就要在ls后跟全路径,否则就会报错.2)命中中的xargs参数加不加效果都一样,不过最好是加上,表示前面的命令输出3)g

ubutun:从共享文件夹拷贝文件尽量使用cp命令而不是CTRL+C/V

为了方便,VBOX安装的Ubuntu,并在硬盘上创建了一个与Windows的共享文件夹sharefolder方便在两个系统之间传文件 但是经常发现的问题就是从sharefolder中拷贝文件到ubuntu中会出现很多毛病,比如说经常按了CTRL+C之后没有拷贝最新的文件(因为你必须在ubuntu自己按F5刷新一下sharefolder以及其子文件夹才能更新里面的全部内容,从而避免拷贝到过期的文件)这是个很麻烦也很容易出错的问题!试想当文件夹内容很复杂的时候吧! 解决办法,使用cp命令即可,输入c

【翻译自mos文章】 使用asmcmd cp命令 把datafile从文件系统移动(move)到asm磁盘组中--针对11gR2

使用asmcmd cp命令 把datafile从文件系统移动(move)到asm磁盘组中--针对11gR2 参考原文: How to Move a Datafile from Filesystem to ASM Using ASMCMD CP Command. (Doc ID 1610615.1) 适用于: Oracle Database - Enterprise Edition - Version 11.2.0.1 to 11.2.0.4 [Release 11.2] Information

Linux中的cp命令&老九门

cp命令详解 cp命令的老九门 我们先看第一种情况: 1.源是一个文件,目标是不存在的 使用 cp aa /testdir/dir1他会创建一个dir1的目标文件,并且将源的内容放到创建的dir目标文件中 2.源是一个文件,目标存在且为文件(上述命令执行后,dir1的文件就会被创建了),然后再次执行cp aa /testdir/dir1,会提示你是否覆盖dir1这个文件,选择y后,再次查看aa和dir1文件的属性,发现dir1的mtime发生了改变说明该文件是被修改了,的确完成了复制. 但是使用

linux中的cp命令

cp命令--文件复制 目录和文件的复制命令 cp命令语法和参数: cp [OPTION]...SOURCE...DIRECTORY -a ALL 等价于dpR -d 复制符号链接源文件时,目标文件也将创建符号链接执行源文件的原始文件 -p preserve 保留文件属性,属主,属组,权限和时间 -r recursive 递归目录下的子文件 示例: [[email protected] ~]# ll /etc/services -rw-r--r-- 1 root root 362031 2006-

关于Linux 中cp命令

0.cp命令 (复制档案或目录) 1.# cp [-adfilprsu] 来源档(source) 目的档(destination) 2.# cp [options] source1 source2 source3 .... directory 参数: -a(archive):相当于 -pdr 的意思:不改变源的所有属性,用于归档复制,常用于备份:= --backup -d(no-dereference):若来源文件为链接文件的属性(link file),则复制连结文件属性而非档案本身:即如果源是

Linux 中 cp 命令(文件复制)

cp命令用来将一个或多个源文件或者目录复制到指定的目的文件或目录.它可以将单个源文件复制成一个指定文件名的具体的文件或一个已经存在的目录下.cp命令还支持同时复制多个文件,当一次复制多个文件时,目标文件参数必须是一个已经存在的目录,否则将出现错误. 语法 cp(选项)(参数) 选项 -a:此参数的效果和同时指定"-dpR"参数相同: -d:当复制符号连接时,把目标文件或目录也建立为符号连接,并指向与源文件或目录连接的原始文件或目录: -f:强行复制文件或目录,不论目标文件或目录是否已存