cp
在什么情况下人们可能希望在目录上使用该命令但尚未拥有它不是是递归的吗?考虑:
$ tree
.
└── old
└── inner
└── a.txt
2 directories, 1 file
$ cp old/inner/ .
cp: omitting directory `old/inner/'
$ tree
.
└── old
└── inner
└── a.txt
2 directories, 1 file
那到底做了什么?那么为什么人们永远不会使用该-r
标志,并且因此为什么在没有指定它的情况下不暗示它呢?请注意,该-r
标志对常规文件没有不良影响:
$ cp -r old/inner/a.txt .
$ ls
a.txt old
我确实意识到我可以别名cp
,cp -r
但我的目标是了解原因是什么,而不是修复任何内容。
答案1
我经常只想复制一个目录中的文件,为什么这会让您觉得奇怪?这取决于您想要做什么。例如,有时我会将项目使用的所有文件放在一个目录中,假设这些文件是我的程序运行所必需的。我还可能有各种包含旧版本或数据文件或其他内容的子目录。如果我想将其传输到服务器以运行我的程序,我只需要文件不是子目录,所以cp
默认值正是我所需要的。
除了有时你会这样做的简单事实不是想要递归复制,一般来说,几乎所有程序都需要显式启用递归。这是标准,也是用户第一次使用该程序时所期望的。因此,将递归设置为默认值并不是一个好主意。需要-r
为递归添加标志是预期的行为,一般来说,默认情况下您不希望递归(想想chmod
或grep
等ls
)。
答案2
递归地复制目录有可能覆盖大量文件。如果您无意中执行此操作,则一个命令可能会造成很大的伤害。默认情况下是非递归的,可确保每次将一个目录复制到另一个目录时,您都会明确执行此操作,因此理论上在执行之前会考虑您输入的内容。
这不是最好的例子,但想象一下如果您不小心键入以下命令而没有意识到两个目标都是目录,会发生什么:
cp /bin /usr # /usr/bin already exists and has important stuff in it
编辑1:一种解决方案是交互式提示用户并询问“您确定吗?”而不是添加显式标志。然而,这并不完全符合 UNIX 哲学:“不要坚持交互式输入”[McIlroy78]。cp
是一个古老的 UNIX 程序,随着时间的推移,它已经发生了一些明显的变化,但这种血统仍然可以在其设计的许多方面看到。
编辑2:我发现了其他几个很好的理由(可能还有更多)。可以在 StackExchange 上找到一个。
由于在 shell 脚本中使用,命令行选项和程序的基本行为既古老又常见,因此
cp
很难更改。某些脚本可能依赖于此行为(拒绝复制目录)。在许多 shell 脚本中,交互式提示也不是您想要的。复制文件和复制目录是两个根本不同的操作,需要概念上独立的命令或选项来处理它们:为什么 unix mv 程序不需要目录的 -R (递归)选项,但 cp 需要它?
[McIlroy78] 贝尔系统技术期刊。贝尔实验室。麦克罗伊医学博士、EN Pinson 和 BA Tague。 “Unix 分时系统前进”。 1978。57(6,第2部分)。 p。 1902年。