我以为a
和a/.
是同一条路径。然而,我发现cp和同步/.
当添加到源路径时,复制目录内容而不是目录本身。我也试过了a/inner/..
;这也奏效了。
$ cp -r a b # Copies dir a into dir b.
$ cp -r a/. b # Copies files from dir a into dir b.
$ cp -r a/inner/.. b # Also copies files from dir a into dir b.
$ cd a && cp -r . ../b # One more way to copy inner files.
我知道这很有用。但我有点困惑,因为这个功能似乎违反了标准。
这是如何工作的?这个功能在某处有记录吗?这是操作系统的一个功能吗?cp还是 bash?
答案1
我知道这很有用。但我有点困惑,因为这个功能似乎违反了标准。
cpa/.
从到递归复制时的行为b
与其“正常”行为完全一致。
默认情况下,cp不会创建父目录。可以使用父母转变:
--parents
use full source file name under DIRECTORY
但是,这是什么意思?
这意味着虽然命令
cp --parents -r some/path/to/source dest
将源目录的内容复制到dest/some/path/to/source
命令中
cp -r some/path/to/source dest
将会把源目录的内容复制到 中dest/source
。
同样,命令
cp -r some/path/to/source/. dest
会将源目录的内容复制到中dest/.
,也就是dest
。
我以为
a
和a/.
是同一条路。
a
和a/.
是相同的路径。但作为论据cp,它只是一个字符串。
请注意命令
cp --parents -r some/path/to/source dest
和
cd some/path/to && cp --parents -r source dest
也会表现不同。
那怎么样
cp -r a/inner/.. b
?考虑到您的解释,它不应该将文件复制到b/..
(即复制到当前目录)吗?
嗯,是的。这是个例外。
至少在 GNU 版本中cp,对于基本名称,有一个特殊情况..
。
if (parents_option)
{
[removed]
}
else
{
char *arg_base;
/* Append the last component of 'arg' to 'target_directory'. */
ASSIGN_BASENAME_STRDUPA (arg_base, arg);
/* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
dst_name = (STREQ (arg_base, "..")
? xstrdup (target_directory)
: file_name_concat (target_directory, arg_base,
NULL));
}
其动机似乎是为了避免复制到目标文件夹之外,尽管这与cp在其他情况下的行为有点违反直觉,并且可能会产生不愉快的后果。
毕竟,我认为没有人会想到这个命令
cp -r .. ~
影响他的主目录之外的文件......
答案2
$ mkdir a b a/inner
$ touch a/a{1..3} b/b{1..3}
$ ls -R
.:
a b
./a:
a1 a2 a3 inner
./a/inner:
./b:
b1 b2 b3
$ cp a b
cp: omitting directory ‘a’
$ cp a/. b
cp: omitting directory ‘a/.’
$ cp a/inner/.. b
cp: omitting directory ‘a/inner/..’
$ cd a && cp . ../b
cp: omitting directory ‘.’
$ cd ..
$ ls -R
.:
a b
./a:
a1 a2 a3 inner
./a/inner:
./b:
b1 b2 b3
您所说的事情实际上都没有发生。这四个cp
命令什么都不做。也许您有一个 loaded 的别名cp
。您可以使用 来检查这一点alias cp
。
答案3
顺便rsync(1)
读一下它的手册小心。它使用了一些不寻常的约定来表示“目录的内容”而不是“目录及其内容”。
对于cp(1)
和其他 Linux 命令,核心levela
甚至引用完全相同的目录。这并不意味着应用程序不能自行解析它们并赋予它们不同的意义,但将字符串发送给内核会更简单,内核会做正确的事情a/.
。a/inner/..
答案4
如果我没记错的话,我相信这个例子中的 . 的作用类似于 *。本质上是一个通配符。