cp --no-target-directory 解释

erc*_*rch 13 directory cp coreutils

问题:我需要一个简单的示例来说明如何使用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`。(来源

Gil*_*il' 19

默认情况下,cp测试其最后一个参数是否为现有目录。如果发生这种情况,请cp在该目录中创建一个链接,其中包含源的基本名称。也就是说,给定命令

cp foo/bar wibble
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

唯一的区别是,-T如果目标是现有目录,则命令会返回错误。当您希望目录不存在时,这很有用:您会收到一条错误消息,而不是出现意外情况。

这同样适用于mvln。如果目标是一个现有目录,带有-T,它们会发出错误信号,而不是默默地做一些不同的事情。

有了cp,情况就不同了。如果进行递归复制并且源是目录,则将cp -T源的内容复制到目标中,而不是复制源本身。也就是说,给定

$ tree source destination 
source
??? foo
destination
??? bar
Run Code Online (Sandbox Code Playgroud)

然后

$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'
Run Code Online (Sandbox Code Playgroud)

然而

% cp -rvT source destination
`source/foo' -> `destination/foo'
Run Code Online (Sandbox Code Playgroud)


Ian*_*len 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
Run Code Online (Sandbox Code Playgroud)

您可以通过后面添加源目录名(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
Run Code Online (Sandbox Code Playgroud)

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