在 12.04 和 16.04 中的 cp 命令中,星号的处理方式不同

在 12.04 和 16.04 中的 cp 命令中,星号的处理方式不同

为了备份 12.04 中的配置文件,我使用了以下语法:

cp -p fstab *.bak

这样做没有问题,文件fstab.bak在同一个文件夹中创建,并且具有与原始文件相同的属性。
在 16.04 中,此命令的工作方式完全不同。它会创建*.bak文件,即原始文件的副本,名称为 asterisk-dot-bak。如果bak此文件夹中已经存在某个扩展名的文件,则它不会执行任何操作并发出警告:

cp:目标“inputrc.bak”不是目录

我认为 12.04 和 16.04 中的通配符工作方式不同。我比较了shopt两个系统中的输出 - 差异很小,通配符选项相同。16.04cp中的 OR 对星号的处理方式与 12.04 中的不同。
有没有办法保留 16.04 中命令的旧行为cp

答案1

这不是通配符出错的情况,而是目录中存在哪些文件:

  1. .bak存在文件。然后*.bak,除非nullglob设置了,否则会扩展为*.bak。因此,运行的命令实际上是cp -p fstab *.bak
  2. Justfstab.bak存在。然后*.bak将扩展为 justfstab.bakcp -p fstab fstab.bak运行。无论存在什么文件,这似乎都是您所期望的。
  3. *.bak存在多个文件(例如,fstab.bakinputrc.bak)。因此,cp -p fstab fstab.bak inputrc.bak运行。在这种情况下,cp期望最后一个参数是目录,或者使用指定目标目录-t。如果不是,它会抱怨。

不要做像 这样的愚蠢的事情cp file *.bak,其结果可能因现有文件而异。你真的想fstab备份到iputrc.bakif fstab.bakwasn't present 和inputrc.bakwas?。如果你懒得输入文件名,请使用括号扩展:

cp -p file{,.bak}

更好的是,使用版本控制和etckeeper而不是脆弱的.bak复制。

相关内容