cp命令:将文件夹正确复制到* nix



本文将揭示一些与复制时使用通配符 ,复制时cp命令的模棱两可的行为以及正确复制大量文件而不会遗漏和崩溃的方法有关的一些非显而易见的内容。

假设我们需要将所有内容从/源文件夹复制到/目标文件夹。

首先想到的是:

 cp /source/* /target 

立即将此命令修复为:

 cp -a /source/* /target 

-a开关将添加所有属性,权限的副本并添加递归。 如果不需要精确复制权限,则-r开关就足够了。

复制后,我们发现并非所有文件都被复制了-从像这样的点开始的文件被忽略:

.profile
.local
.mc

等等。

为什么会这样呢?

因为通配符处理shell(在典型情况下为bash )。 默认情况下,bash将忽略所有以句点开头的文件,因为它将其视为隐藏文件。 为了避免这种行为,我们必须使用以下命令更改bash的行为:

 shopt -s dotglob 

要在重新引导后保存此行为更改,可以使用此命令在/etc/profile.d文件夹中创建wildcard.sh文件(您的发行版可能具有其他文件夹)。

而且,如果源目录中没有文件,则Shell无法用任何东西代替星号,并且复制也会失败。 在这种情况下,存在failglobnullglob 。 我们需要设置failglob ,这将阻止命令执行。 nullglob将不起作用,因为它将带有未找到匹配项的通配符的字符串转换为空字符串(长度为零),这将导致cp错误。

但是,如果文件夹中有成千上万个文件,甚至更多,那么应该完全放弃使用通配符的方法。 事实是, bash将通配符扩展为一个很长的命令行,例如:

 cp -a /souce/a /source/b /source/c …… /target 

命令行的长度是有限制的,我们可以使用以下命令来查找:

 getconf ARG_MAX 

获取命令行的最大长度(以字节为单位):

 2097152 

或者:

 xargs --show-limits 

我们得到类似:

 …. Maximum length of command we could actually use: 2089314 …. 

因此,让我们完全不用通配符。

让我们写

 cp -a /source /target 

在这里,我们将遇到cp行为的歧义。 如果/ target文件夹不存在,那么我们将获得所需的东西。

但是,如果目标文件夹存在,则文件将被复制到/ target / source文件夹。

我们并非总是可以提前删除/ target文件夹,因为它可能包含我们需要的文件,例如,我们的目标是使用/ source中的文件将文件添加到/ target中。

例如,如果源文件夹和目标文件夹的命名方式相同,我们将从/ source复制到/ home / source,则可以使用以下命令:

 cp -a /source /home 

在/ home / source中复制文件后,将是/ source的补充文件。

这是合乎逻辑的任务:我们可以将文件添加到目标目录,如果文件夹的名称相同,但是如果名称不同,则源文件夹将放置在接收方内部。 如何在不使用通配符的情况下使用cp将文件从/源复制到/目标?

为了解决这一有害限制,我们使用了非显而易见的解决方案:

 cp -a /source/. /target 

那些熟悉DOS和Linux的人已经了解了一切:每个文件夹中都有2个不可见的文件夹“”。 和“ ..”,它们是指向当前目录和更高目录的伪文件夹链接。

  • 复制时, cp检查是否存在并尝试创建/ target /。
  • 这样的目录存在,它是/ target
  • 来自/源的文件已正确复制到/目标。

因此,我们在记忆中或墙上悬挂着一个大胆的框架:

 cp -a /source/. /target 

该命令的行为是明确的。 不管您有百万个文件还是根本没有文件,一切都会正常运行。

结论


如果要将所有文件从一个文件夹复制到另一个文件夹,则不要使用通配符,而最好使用cp和源文件夹末尾的点来代替通配符。 这将复制所有文件,包括隐藏的文件,并且不会因数百万个文件或完全没有文件而失败。

后记


vmspike建议使用类似的命令变体:

 cp -a -T /source /target 

Oz_Alex
 cp -aT /source /target 

注意:字母T的大小写很重要。 如果将它们混合在一起,则会得到完整的垃圾:复制的方向将会改变。

致谢:

  • RUVDS.COM公司的支持以及有机会在Habré的博客上发布。
  • 每个图像TripletConcept 。 图片很大很详细,您可以在一个单独的窗口中打开它。

您在PM中注意到的PS Direct错误。 我为此增加业力。



Source: https://habr.com/ru/post/zh-CN471092/


All Articles