cp --no-target-directory 解释

cp --no-target-directory 解释

问题:我需要一个简单的例子来说明如何使用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/destmv -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,如果目标是现有目录,该命令将返回错误。当您期望目录不存在时,这非常有用:您会收到一条错误消息,而不是发生意外的情况。

这同样适用于mvln。如果目标是现有目录,则-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’

相关内容