cp --no-target-directory说明


10

问题:我需要一个有关如何使用的简单示例cp --no-target-directory

我的理解确实有些困难cp --no-target-directory。我确实理解了解释mv --no-target-directory,但我真的无法想象将其用于的方法cp

例如,命令mv /tmp/source /tmp/dest成功执行后,不能保证将/tmp/source其重命名为/tmp/dest/tmp/dest/source如果将其他进程创建/tmp/dest为目录,则可以将其重命名为。但是,如果mv -T /tmp/source /tmp/dest成功,毫无疑问/tmp/source was renamed to/ tmp / dest`。(来源

Answers:


15

默认情况下,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'

8

你可以使用--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

您可以通过后面添加源目录名(S)与达到同样效果的东西斜线点/.为: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

仅内容副本不会将源目录的模式或时间戳传递到目标目录。


2

接下来呢?

$ 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’

使用[out] --no-target-directory选项为我工作:只要使用--recursive,一切就可以[ coreutils 8.12在GNU / Linux下使用]。主要区别在于,--no-target-directory使用内容而不是复制目录本身[研究仍在进行中]
erch 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.