1.root和普通用户
在Windows里面,管理员Administrator是所有用户里面权限最高的,很多文件都会提示请使用管理员打开等。但在整个Windows系统中,管理员的权限并不是最大的,System优先级更高,因此我们系统中的某些文件是动不了的。
在Linux中,当我们创建系统后就可以使用root账号登录,和Windows里面的管理员不一样,管理员还受System限制,但在Linux里root不受任何限制,它就是最高权限。
当然在我们创建系统之后,我们还可以创建普通账户,在root账号下才能进行相关账户的管理:adduser 用户名 新增账户、passwd 用户名 设定密码、userdel 用户名 删除普通账户
在Linux只有两种用户,一种叫root,另一种叫普通账户。这其实是按照权限来区分的,只有普通账户才会受到权限制约,而root无视一切权限限制规则。这一点需要我们在接下来不断加深理解。
2.权限的理解
要进一步了解权限,我们需要从生活中抽象概念。当一个领导张三上台讲话,为什么台下的人要听它的?是因为它是领导还是因为它是张三?张三是人的名字,领导是该人的身份,他所拥有权限取决于这个人的身份,人和其身份是强绑定的,并且在不同的地方该人的身份并不一样。所以我们可以认为:权限 = 人 + 人的身份。
在Linux用户中也是这个道理,用户的权限 = 用户 + 该用户对于该文件的权限属性。对于普通用户,它在每个文件那里的身份都不一样,就像张三在公司是领导,回家就是丈夫。用户的身份就是此普通用户对于要操作文件的权限属性。但是对于root用户,情况就发生改变了。在人类社会,权限终归到底是限制普通人的,对于普通人而言,权限 = 人 + 人的身份,这才构成社会的稳定。但对于绝对领袖来说,一切规则在他那里都是不适用的。root就是Linux里面的绝对领袖,对于root而言,后面讲的所有权限的规则对它都不适用。它的权限甚至可以直接删除整个系统,即使有的文件正在使用无法删除,但root会将能删的都删了,当退出系统后,剩余的文件也一并带走。也就是说,root甚至可以摧毁自己,因为root也是Linux的一部分,而root可以操作Linux里面的一切文件。
3.文件、目录
在Linux里面,一切皆为文件(文件+目录)。也就是说,Linux里,我们执行的每一条指令、执行的每一项服务都是对文件或者目录进行操作。如C/C++中的printf、cout和指令echo就是向显示器文件写入,scanf、cin就是从键盘文件写入。也就是说,用户的身份就是该用户在要操作的文件或者目录处拥有的权限属性。
(1)文件
文件 = 文件的内容 + 文件的属性
文件的内容存储在磁盘的特定区域。但是文件并不只有内容,我们新建一个文件之后还要存储它的属性信息,如修改时间、最新执行时间、大小等信息。这些属性信息专门存在一个区域,叫做inode,每个inode都有自己的编号(inode编码,也叫硬链接),相当于存储信息空间的指针。
需要特别注意的是inode里面除了属性之外还存储的有指向文件内容的指针,这样才能通过inode找到文件内容,并且文件名是单独存的,并不在inode里面,我们可以认为文件名和inode组成了一个一个键值对。
下面是文件存储的结构图
(2)目录
目录 = 目录的内容 + 目录的属性
目录的内容是该目录下所有文件的文件名及其inode编码,我们可以理解为一个一个的键值对。目录的属性除了常规的大小、时间、权限属性等之外,还有该目录下面文件或目录的数量(注意仅仅是数量,并且还包括了.和..)。
目录的属性同样是单独存在inode里面,每个inode有单独的编号,相当于指针。目录的名字不存在inode里,可以理解为目录名与inode编号形成键值对。
下面是目录存储的结构图
有人会想,目录中不仅可以存文件,还可以存目录,事实上,刚刚的解释完全适用于这种嵌套结构,因为不管是目录还是文件,它们在上层目录的内容中就只是名字+inode编码的键值对而已。并且透过目录的inode我们最多看得到该目录下的子文件有多少个,并看不到具体信息。也就是说,上层目录并不能看到下层目录的存储的文件的具体属性。
(3)文件和目录的删除
删除文件和目录采用rm,会先将文件(目录)名和inode编码删掉。要注意这个时候inode和文件(目录)内容并不会立刻删除,而是有一个判断过程。我们前面说过inode编码是指向inode的指针,准确来说应该是shared_ptr,可能有很多inode编码都指向这个inode,inode里面就藏有一个引用计数,像shared_ptr那样,当没有inode编码指向这块空间之后,系统就会自动将inode以及文件(目录)的内容回收,达到真正意义上的删除。
4.目录和文件的权限
(1)文件
文件一共有三种权限:r读,w写,x执行,-表示该用户不具备此权限。因此对于一个文件而言,拥有它的全部权限写作rwx,没有它的全部权限写作---。
r读具体而言是访问文件内容的权限,但并没有访问文件的属性的权限。
w写具体而言是修改文件内容的权限,但并没有修改文件的属性的权限,进一步讲就是不能修改文件的inode编码。也就是说,rm并不能删除有w权限的文件,因为删除一个文件的前提就是要先删掉它的inode和文件名。
x执行就是执行该文件。但我们要注意,有该文件的执行权限并不意味着就能执行它,它得首先是一个可执行程序才行。
(2)目录
目录也有三种权限:r读,w写,x进入目录,-表示用户不具备此权限。
r读通常被认为是访问目录内容的权限,但实际上并不是。
我们知道目录的内容是目录下文件或目录的名字和它们的inode编码。但实际上目录内容的访问权限被分散了,inode编码的访问权被交给x(进入目录)了。也就是说,只要我们有目录的x权限,我们就能访问该目录下的文件的属性。
如果我们只有r没有x,我们只能访问其目录文件名字,但看不到它的权限
也就是说r掌管的其实是目录下文件的名字的访问权,而inode编码的访问权交给了x
w写权限也是如此,修改inode的权限交给了x,这就导致mv改名字必须要同时具备wx两个权限才可操作,因为改名字会修改文件的修改时间。
单x不能修改名字,因为w管理目录下文件的名字
单w也不行,因为改名字也会修改文件属性,属性是x在掌管
拥有目录的wx才能修改名字,当修改的时候,不需要有原先名字的访问权限,因为系统能定位到文件,我们也显式地写出文件名了,且修改名字本来也不需要关系它曾经的名字,所以就不需要r权限
至于拷贝cp就要考虑更多了。首先复制一个文件需要访问该文件的属性,即目录的x权限;其次还要访问文件的内容,需要文件的r权限。
就算目录有访问文件名、属性的权限也不能复制。复制需要属性复制+内容复制,内容复制不由目录权限管
当文件有r属性,目录有x属性我们就能进行复制了,属性和内容都能访问当然就可以复制了,我们要理解背后的逻辑
cp不指定拷贝后的名称默认是以拷贝前的文件的名称,但在这里我们没有r属性为什么也可以访问文件名呢?
事实上如果没有r,操作系统确实不能访问文件的名称,但是我们都已经显式地写出我们需要拷贝地文件名了,操作系统直接到我们写的路径中取就可以了,根本不用走访问文件名这种操作。
Linux目录的权限规则非常细,特别是目录内容inode权限分离给x需要我们体会。当我们需要对文件进行操作时,我们应从规则入手,问自己我要修改什么?修改的东西受到哪些权限的限制?即时推导,而不是死记硬背。