这个答案揭示了可以将所有文件(包括隐藏文件)从目录复制src
到目录中,dest
如下所示:
mkdir dest
cp -r src/. dest
答案或其评论中没有解释为什么这实际上有效,似乎也没有人找到这方面的文档。
我尝试了一些事情。首先,正常情况:
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src dest
$ ls -A dest
dest_file src
然后,/.
最后:
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/. dest
$ ls -A dest
dest_file .dotfile src_dir src_file
因此,其行为与 类似*
,但也会复制隐藏文件。
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/* dest
$ ls -A dest
dest_file src_dir src_file
.
和..
是正确的硬链接在这里解释,就像目录条目本身一样。
这种行为从何而来,在哪里记录?
答案1
该行为是记录算法的逻辑结果cp -R
。看POSIX,步骤 2f:
目录中的文件源文件应复制到该目录目标文件,执行此处列出的四个步骤(1 到 4),文件为源文件。
.
和..
是目录,分别是当前目录和父目录。就 shell 而言,两者都不是特殊的,因此两者都不涉及扩展,并且目录将被复制,包括隐藏文件。*
另一方面,将扩展为文件列表,这就是隐藏文件被过滤掉的地方。
src/.
是里面的当前目录src
,也就是src
它本身;src/src_dir/..
issrc_dir
的父目录,又是src
.因此,从外部来看src
,如果src
是目录,则指定src/.
或src/src_dir/..
作为源文件cp
是等效的,并复制 的内容src
,包括隐藏文件。
指定的要点是,如果不是目录(或目录的符号链接),src/.
它将失败,反之则不会。它还会只复制内容,而不复制自身;这也符合文档:src
src
src
src
如果目标存在并命名一个现有目录,文件层次结构中每个文件的相应目标路径的名称应为串联目标,单个斜杠字符(如果目标不以斜杠结尾),以及文件相对于包含的目录的路径名源文件。
因此复制tocp -R src/. dest
的内容(源文件位于),而复制to的内容(源文件位于)。src
dest/.
.
src
cp -R src dest
src
dest/src
src
另一种思考方式是比较复制src/src_dir
和src/.
,而不是比较src/.
和src
。.
行为就像src_dir
前一种情况一样。
答案2
当你跑的时候cp -R src/foo dest
,你就会得到dest/foo
。因此,如果目录dest/foo
不存在,cp
将创建它,然后将内容复制src/foo
到dest/foo
.
当您运行时cp -R src/. dest
,cp
会看到dest/.
存在,然后只需将内容复制src/.
到即可dest/.
。
当您将其视为复制名为.
from 的目录src
并将其内容与现有目录合并时dest/.
,它就有意义了。