/ 之间的差异复制内容文件夹。和 /* 在 Linux 中

/ 之间的差异复制内容文件夹。和 /* 在 Linux 中

要从我读过的文件夹中复制内容,请使用:

cp -rfva ../foldersource/. ./

但这也有效

cp -rfva ../foldersource/* ./

有什么区别吗?

举例来说,如果我想从带有 . :

rm -rf ../foldersource/.

我收到错误:

rm:  rejet delete folder '.' or '..':

但带星号就可以了

rm -rf ../foldersource/*

那么,星号是在任何地方都适用的更好选择吗?

答案1

这两种论证形式之间存在根本区别。了解正在发生的事情非常重要。

参数../foldersource/.会原封不动地传递给命令,无论它是cprm其他东西。尾随点是否具有特殊或独特的语义,与简单地指向它所在目录的标准 Unix 约定不同,这取决于命令;两者rm似乎cp都将其视为特殊情况。

../foldersource/*首先由 shell 扩展该命令甚至会被执行并传递任何参数。因此,rm从未见过../foldersource/*;它看到扩展版本../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1等等。这很重要,因为操作系统限制可以传递给命令的参数数量,通常只有几百个。

答案2

当您使用复制时,cp -a source/* target/您会将大部分文件和目录从 复制sourcetarget。具体来说,被排除的项目可能是 .txt 文件.的顶层以点 ()开头的文件source

考虑这些文件(或目录)source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will not be copied

当您使用 进行复制时,cp -a source/. target/您将复制 的全部内容source,包括以点 ( .) 开头的任何项目到target

考虑这些文件(或目录)source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will be copied

如果您使用bash, zsh,则可以使用dotglob选项更改 的含义,*使其包含以点开头的文件和目录(yash也有一个dotglob选项;但是,它随后在 glob 扩展中包含.and ..,这限制了其可用性。另请参阅FIGNORE='@(.|..)'ksh93

有趣的是,cp -a source/. target/有保证绝不创建组件target/source。 (另一方面,cp -a source target/将根据是否target已存在执行两件事之一。请参阅如何使用 cp 以幂等方式递归复制文件夹了解详情。)


使用删除时,您将删除其中不以点 ( ) 开头rm -rf source/*的文件和目录。取决于我已经提到的设置。它不会删除目录本身。source.dotglobsource

当您尝试使用它删除时,rm -rf source/.它将失败 - 如其他人已经解释过- 因为 POSIX 禁止删除最后一个组件是.或 的路径..。最接近的等效项是rm -rf source,它将删除source目录及其所有内容,无论它们是否以点 ( .) 开头。

答案3

您不能这样做,rm -rf ../foldersource/.因为rm不允许这样做,如手册中明确指出的:

任何删除最后一个文件名部分为“.”的文件的尝试或 '..' 在没有任何提示的情况下被拒绝,按照 POSIX 的规定。

在 POSIX 手册中man 1p rm我们看到:

如果文件 dot 或 dot-dot 被指定为操作数的基名部分(即最终路径名部分),或者如果操作数解析为根目录,则 rm 应将诊断消息写入标准错误并且不执行任何操作更多这样的操作数。

相关内容