如何使用 cp 复制以包含隐藏文件和隐藏目录及其内容?

ele*_*n81 533 unix cp recursive

如何绝对cp -r复制目录中的所有文件和目录

要求:

  • 包括隐藏文件和隐藏目录。
  • 是一个带有标志的单个命令以包含上述内容。
  • 根本不需要依赖模式匹配。

我丑陋但有效的黑客是:

cp -r /etc/skel/* /home/user
cp -r /etc/skel/.[^.]* /home/user
Run Code Online (Sandbox Code Playgroud)

如何在没有模式匹配的情况下在一个命令中完成这一切?我需要使用什么标志?

Bru*_*ira 613

假设您创建了新文件夹(或将要创建一个)并希望在创建文件夹后将文件复制到其中

mkdir /home/<new_user>
cp -r /etc/skel/. /home/<new_user>
Run Code Online (Sandbox Code Playgroud)

这将递归地将所有文件/文件夹从/etc/skelin复制到在第一行创建的现有文件夹中。

  • 对我来说效果很好。注意'.' 对它的工作至关重要。 (57认同)
  • @Technext bash 中的默认通配符不包含以`.` 开头的文件名,要更改您需要使用`shopt -s dotglob` 命令才能包含这些文件。因此,使用 `*`,默认情况下,您要求从该目录中递归复制所有文件,这些文件可以使用 `*` 扩展(默认情况下不包括隐藏文件)。在另一端使用 `.` 时,您使用 cp 递归复制“此目录”中的所有内容。 (46认同)
  • 它有效,但是,为什么?在手册中找不到对此的参考。 (14认同)
  • 如果我没有弄错,这不会复制隐藏/点文件。 (6认同)
  • 我认为它有效,因为通常情况下,这会创建一个新文件夹,其中第一个参数中的最后一个文件夹的名称。但是,由于该名称是“.”,因此此行为将要求它创建一个已经存在的目录,因此它只是跳过该步骤。 (5认同)
  • 这样做的原因是它等价于 `cp -r /etc/skel /home/&lt;new_user&gt;`。点`.`是“_This directory_”的shell等效名称,就像双点`..`表示相对于给定路径的“_向上一个目录_”。这是一个相对路径说明符。试试这个: `ls -d /etc/skel/.` 你应该看到 bash `eval`s 到:`/etc/skel/.` 如果你尝试 `ls -l /home/&lt;myuser&gt;/ .`,你会在 `/home/&lt;myuser&gt;` 中看到文件 (3认同)
  • 这应该是一个可接受的答案 (3认同)
  • 请注意,答案不仅适用于OP,也适用于通过网络搜索找到该页面的任何人。 (2认同)

Ran*_*son 336

不要指定文件:

cp -r /etc/skel /home/user

(注意/home/user不能已经存在,否则会创建/home/user/skel。)

  • 如果`/home/user/skel` *确实*存在,是否可以使用类似的东西? (81认同)
  • @bradley.ayers Bruno 在下面的回答解决了您的问题 (8认同)
  • 回答一个 7.5 年前的问题,你可以运行 `cp -r /etc/skel/. /home/user` 以避免创建子目录(注意 etc/skel 后面的 `/.`)。 (5认同)
  • 这个解决方案对我不起作用。它没有复制隐藏文件。我正在使用 CentOS 6.5 版。@Bruno 的解决方案成功了。 (3认同)
  • 在 ubuntu/debian 下,这将目录 'skel' 放在目标目录中,而不是 skel 中的递归文件。使用`-T`(无目标)按照下面的正确使用。(`-rT` 表示递归) (2认同)

小智 177

这样做的正确方法是使用该-T (--no-target-directory)选项,并递归复制文件夹(没有尾部斜杠、星号等),即:

cp -rT /etc/skel /home/user
Run Code Online (Sandbox Code Playgroud)

这将复制/etc/skelto的内容/home/user(包括隐藏文件),/home/user如果文件夹不存在则创建该文件夹;但是,如果该文件夹存在,该-T选项会阻止 的内容/etc/skel被复制到新文件/home/user/skel夹中/home/user

  • 正确答案。+1 (10认同)
  • 这是这群人中最好的答案;这是唯一能解决问题而不使问题复杂化的方法 (7认同)
  • 不适用于 Mac :( (6认同)
  • 当您为一种情况使用正确的 cmd 标志时,会喜欢它。 (3认同)
  • 唉,并非所有版本的“cp”都支持,但是当它存在时就很棒了。 (3认同)

Per*_*ulf 75

bash本身有一个很好的解决方案,它有一个shell option,你可以cpmv等等:

shopt -s dotglob # for considering dot files (turn on dot files)
Run Code Online (Sandbox Code Playgroud)

shopt -u dotglob # for don't considering dot files (turn off dot files)
Run Code Online (Sandbox Code Playgroud)

以上解决方案是标准的 bash

笔记:

shopt # without argument show status of all shell options
-u # abbrivation of unset 
-s # abbrivation of set
Run Code Online (Sandbox Code Playgroud)

  • 这是 zsh 的 `setopt`,以防其他人想知道。 (7认同)
  • 当您只想复制内容而不在目标中创建新目录时,这很有用。特别是当目标目录是挂载点时。 (2认同)

小智 33

使用 rsync:

rsync -rtv source_folder/ destination_folder/


小智 7

rsync 很好,但另一种选择:

cp -a src/ dst/
Run Code Online (Sandbox Code Playgroud)

从主要帮助:

   -a, --archive
          same as -dR --preserve=all

   -d     same as --no-dereference --preserve=links

   -R, -r, --recursive
          copy directories recursively
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您的源目录和目标目录具有相同的名称,即使目标目录存在,您也可以简单地键入:

cp -R /etc/skel /home/
Run Code Online (Sandbox Code Playgroud)

这会将 /etc/skel 目录复制到 /home/ 中,包括隐藏文件和目录。

最后,您可以复制该目录并在一行中重命名它:

cp -R /etc/skel /home/ && mv /home/skel /home/user
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用 rsync。

rsync -aP ./from/dir/ /some/other/directory/
Run Code Online (Sandbox Code Playgroud)

你甚至可以通过 ssh 复制

rsync -aP ./from/dir/ username@remotehost:/some/other/directory/
Run Code Online (Sandbox Code Playgroud)

您可以使用多种标志:-a, --archive # archive (-rlptgoD)

-r, --recursive
-l, --links      # copy symlinks as links
-p, --perms      # preserve permissions
-t, --times      # preserve times
-g, --group      # preserve group
-o, --owner      # preserve owner
-D               # --devices --specials

--delete         # Delete extra files

You may want to add the -P option to your command.

--partial        # By default, rsync will delete any partially transferred file if the transfer is interrupted. In some circumstances it is more desirable to keep partially transferred files. Using the --partial option tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.

-P               # The -P option is equivalent to --partial --progress.   Its  purpose  is to make it much easier to specify these two options for a long transfer that may be interrupted.
Run Code Online (Sandbox Code Playgroud)

Rsync 手册页


sim*_*eco 5

最简单的方法是:

cp -r /etc/skel/{.,}* /home/user
Run Code Online (Sandbox Code Playgroud)

该表达式{.,}*包括所有文件和目录(也以点开头)。

如果您不想使用上述表达式,则可以使用该cp属性,即为一个目标文件夹指定多个源的能力:

cp -r /etc/skel/* /home/user
Run Code Online (Sandbox Code Playgroud)

  • 这会错过诸如“..anything”或“...anything”等文件。 - /sf/answers/2200684881/ 包含此问题的正确正则表达式。**||** 但无论如何使用 `shopt -s dotglob` 仍然是更好的解决方案! (2认同)
  • 抱歉,文字错误!- 你的答案的问题是,它还会考虑“.”和“..”(相当于当前及其包含的文件夹)。**||** 但[链接中的答案](/sf/answers/2200684881/) 进一步解释了它并提供了解决方案。 (2认同)