问题:我需要一个简单的例子来说明如何使用cp --no-target-directory
.
我确实在理解上遇到了一些困难cp --no-target-directory
。我明白的解释mv --no-target-directory
,但我真的无法想象将其用于 的方法cp
。
例如,当命令
mv /tmp/source /tmp/dest
成功时,不能保证被/tmp/source
重命名为:如果将其他进程创建为目录,则/tmp/dest
它可能已重命名为。但是,如果成功,那么/tmp/dest`就毫无疑问了。 (/tmp/dest/source
/tmp/dest
mv -T /tmp/source /tmp/dest
/tmp/source was renamed to
来源)
答案1
默认情况下,cp
测试其最后一个参数是否是现有目录。如果发生这种情况,则cp
在该目录内创建一个带有源的基本名称的链接。也就是说,给定命令
cp foo/bar wibble
如果wibble
是现有目录则将cp
源复制到wibble/bar
.如果wibble
不存在则将cp
源链接到wibble
。
如果您想确保副本始终为wibble
,则可以指定--no-target-directory
(alias -T
) 选项。这样,如果cp
成功,您可以确定该副本被调用wibble
。如果wibble
已经作为目录存在,则将cp
失败。
以表格形式:
The target is … Without -T With -T
existing directory copy in the directory error
existing file (not dir) overwrite overwrite
does not exist create create
唯一的区别是-T
,如果目标是现有目录,该命令将返回错误。当您期望目录不存在时,这非常有用:您会收到一条错误消息,而不是发生意外的情况。
这同样适用于mv
和ln
。如果目标是现有目录,则-T
它们会发出错误信号,而不是默默地执行不同的操作。
对于cp
,有一种不同的情况。如果执行递归复制并且源是目录,则将cp -T
源的内容复制到目标,而不是复制源本身。也就是说,给定
$ tree source destination
source
└── foo
destination
└── bar
然后
$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'
然而
% cp -rvT source destination
`source/foo' -> `destination/foo'
答案2
--no-target-directory
如果您不想复制源目录,则可以使用下现有的目标目录,您想要复制源目录到目标目录。
以下是包含和不包含 的目录副本的示例--no-target-directory
:
$ mkdir a
$ touch a/b a/c
$ find
.
./a
./a/c
./a/b
$ cp -r a b # b does not exist; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r a b # b already exists; a is copied *underneath* it
$ find
.
./b
./b/a
./b/a/b
./b/a/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r --no-target-directory a b # b already exists; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
您可以通过在源目录名称后添加斜杠点来实现相同的效果,/.
如下所示:cp -r a/. b
复制源目录a
到 b
并不是下 b
。
上述两种方法都与“仅将源目录的内容复制到现有目标目录”不同,因为如果您要求保留时间和权限,现有目标目录将获取源目录的时间和权限。一个例子(编辑以删除不必要的信息):
$ find . -ls
drwx------ Oct 13 13:31 ./b # note date and permissions
drwxr-xr-x Jan 1 2013 ./a # note date and permissions
-rw-r--r-- Oct 13 13:23 ./a/c
-rw-r--r-- Oct 13 13:23 ./a/b
$ cp -rp --no-target-directory a b # preserve mode and timestamps
$ find . -ls
drwxr-xr-x Jan 1 2013 ./b # note copied date and permissions
-rw-r--r-- Oct 13 13:23 ./b/b
-rw-r--r-- Oct 13 13:23 ./b/c
drwxr-xr-x Jan 1 2013 ./a
-rw-r--r-- Oct 13 13:23 ./a/c
-rw-r--r-- Oct 13 13:23 ./a/b
仅内容副本不会将源目录的模式或时间戳传输到目标目录。
答案3
下面的怎么样?
$ cp -rvT Dir_1 Dir_2
‘Dir_1/File_3.txt’ -> ‘Dir_2/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/File_2.txt’
$ cp -rv Dir_1 Dir_2
‘Dir_1’ -> ‘Dir_2/Dir_1’
‘Dir_1/File_3.txt’ -> ‘Dir_2/Dir_1/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/Dir_1/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/Dir_1/File_2.txt’
因此,这只是一种不同的写作方式cp Dir_1/* Dir_2/
。但是,它确实捕获了 Dir_1 根目录下的隐藏文件,而简单的cp *
.
$ touch Dir_1/.Hidden_File_{1,2,3}.txt
$ cp -rv Dir_1/* Dir_2
cp: No match.
$ cp -rvT Dir_1 Dir_2
‘Dir_1/.Hidden_File_2.txt’ -> ‘Dir_2/.Hidden_File_2.txt’
‘Dir_1/.Hidden_File_3.txt’ -> ‘Dir_2/.Hidden_File_3.txt’
‘Dir_1/.Hidden_File_1.txt’ -> ‘Dir_2/.Hidden_File_1.txt’