我的问题是为什么-r
在制作目录副本时需要使用(递归)标志?即,为什么要这样做:
$ cp -r dir1 copyDir1
Run Code Online (Sandbox Code Playgroud)
复制目录时我什么时候不想要这种行为?
目录的递归副本不是真正的“默认”行为吗?我们几乎一直想要的行为?
感觉这是一个多余的标志。
Gia*_*968 59
文件系统的工作方式,目录实际上不是包含文件的文件夹,而是目录是包含指向连接到它的“子”文件的inode 指针的文件。这意味着,从文件系统的角度来看,文件是一个文件,而目录只是一个包含连接文件列表的文件。
所以从命令行的角度来看,这样做:
$ cp dir1 copyDir1
Run Code Online (Sandbox Code Playgroud)
基本上意味着将名为的文件复制dir1
到名为copyDir1
. 就文件系统而言,dir1
无论如何都只是一个文件;它是一个“目录”的事实只有在文件系统实际检查dir1
以查看那堆位实际上是什么时才会明显。
该-r
标志告诉文件系统递归地向下滚动文件/目录树,并将可能是该文件的“子”的任何和所有内容复制到新位置。
现在至于为什么这似乎是多余的或多余的,这实际上归结为处理文件系统的历史方法。以及创建一个可以避免所有类型的用户相关错误的系统;有意外也有故意。
意思是,假设~/bin
您的主目录中有一个文件要复制,但不小心遗漏了 -~
因为您是人并且会犯错误 - 所以它/bin
就像这样:
cp /bin/ ~/copy_of_bin
Run Code Online (Sandbox Code Playgroud)
有了/bin
作为目录的“安全网”以及对-r
标志的需求,您将避免意外地将您所在系统的整个二进制根目录复制到您的主目录中。如果那个安全网不存在,就会发生轻微的——或者可能是重大的——灾难。
这里的逻辑是,在 GUI(图形用户界面)之前的时代,需要设置逻辑/行为约定,以避免用户创建可能导致系统崩溃的事故。-r
现在使用标志就是其中之一。
如果这看起来是多余的,那么只需看看可以放在 Linux 文件系统之上的现代 GUI 系统。GUI 通过允许用户轻松拖放文件和目录来解决此类基本用户问题。
但在基于文本的界面领域,该世界中的许多“用户体验”基本上只是基于逻辑和色调的道路颠簸,有助于让用户保持控制,从而避免潜在的灾难。
类似地,这就是为什么 Linux/Unix 文件系统没有默认设置的777
权限和sudo
权限,以及当用户设置777
权限或授予每个sudo
人权限时,真正的系统管理员如何畏缩。这些是确保系统稳定和尽可能“用户证明”的基本事情;任何急于打破这些约定的人很可能在不知情的情况下对他们的系统造成损害。
附加信息: Unix Stack Exchange 站点上的另一个答案很好地解释了为什么目录的非递归副本有问题;重点是我的。
好吧,如果没有 -R 标志,则只能复制文件,因为有人想要非递归复制目录是很不寻常的:非递归复制只会导致目录的第二个名称,直接指向相同的目录结构。 因为这很少是人们想要的,而且实际上有一个单独的程序可以执行此操作 (ln),因此不允许目录的非递归副本。
因此,如果一个目录实际上只是一个包含 inode 项的文件,那么直接复制该文件就相当于硬链接的工作方式。这不是任何人想要的。
loo*_*bee 19
确实,这是我们几乎一直想要的行为。但是,这并不一定意味着递归复制应该是默认行为。
我认为原因cp
确实源于Unix 哲学。Unix 偏爱只做一件事并把它做好的程序,以及接口和实现都简单的程序(有时称为越糟越好)。
这里难题的关键部分是意识到cp
不复制目录 -cp
复制文件(并且仅复制文件)。如果要复制目录,cp
递归调用自身,以便复制每个目录上的文件。
当然,从用户的角度来看,“复制目录”和“递归复制文件”之间的区别是绝对没有的,但是拥有这个接口有助于实现保持简单。
如果您cp
能够复制目录,您很快就会想添加更多仅对目录有意义的功能 - 例如,您可能只想复制以.sh
. 不可避免地,这会导致我们在其他操作系统中习惯的膨胀和功能蠕变——使软件变得缓慢、复杂和容易出错。
另一个优点是-r
还可以帮助用户了解界面下真正发生的事情。这样做的一个很好的副作用是,当您了解支持递归操作的其他工具(例如grep
,例如)时,学习递归操作的概念将为您节省一些工作
有些人肯定会告诉你,将实现细节暴露给用户是不好的,拥有更多的特性是好的。我在这里的目的只是解释这种行为的基本原理,所以我不会试图以任何方式争论。
与目录的交互确保您知道您正在与目录交互,而不仅仅是与单个文件交互。
例如:
$ tree
.
??? folder1
??? sub1
??? subsub1
3 directories, 0 files
$
$ cp folder1/ folder2
cp: folder1/ is a directory (not copied).
$
$ mkdir blah
$ cp blah/ blah2
cp: blah/ is a directory (not copied).
$ rm blah/
rm: blah/: is a directory
Run Code Online (Sandbox Code Playgroud)
因此,如果您想成功复制文件夹,因为它意味着文件夹和与引用文件夹相关的对象,您必须将其视为文件集合:
$ cp -r folder1/ folder2
$ rm -rf folder1
Run Code Online (Sandbox Code Playgroud)
小智 5
该标志的一个明显优点-r
是您可以仅将源目录中的所有文件cp * /target/dir
复制到目标目录中,忽略(尽管有警告)其中包含的所有目录。会复制所有内容,包括子目录。cp -r * /target/dir
归档时间: |
|
查看次数: |
26763 次 |
最近记录: |