文章目录
-
- 第四章:Linux权限的概念:从底层逻辑到阶级跃迁
- [一) 为什么我们需要权限?(Linux 的"合租房"哲学)](#一) 为什么我们需要权限?(Linux 的“合租房”哲学))
-
-
- [1. 天生的"多用户"基因(合租房逻辑)](#1. 天生的“多用户”基因(合租房逻辑))
- [2. 极致的防毒与隔离机制(防爆舱)](#2. 极致的防毒与隔离机制(防爆舱))
- [3. 保护"瞎子"内核(防止自毁)](#3. 保护“瞎子”内核(防止自毁))
-
- [二) 权限=人+文件属性](#二) 权限=人+文件属性)
-
- [1) 绝对阶级:Linux 村的三大居民类型 (User)](#1) 绝对阶级:Linux 村的三大居民类型 (User))
-
- [1. 村长:Root(超级管理员)](#1. 村长:Root(超级管理员))
- [2. 平民:普通用户(如 `xiaoli`, `nanlin`)](#2. 平民:普通用户(如
xiaoli,nanlin)) - [3. 隐形打工人:系统用户(如 `mysql`, `nginx`)](#3. 隐形打工人:系统用户(如
mysql,nginx))
- 补充:root和普通用户之间的互相转换
-
- [第一招:灵魂夺舍 ------ `su` (Switch User)](#第一招:灵魂夺舍 ——
su(Switch User)) -
- [1. 不彻底的变身:`su root` (或者直接敲 `su`)](#1. 不彻底的变身:
su root(或者直接敲su)) - [2. 完美的灵魂夺舍:`su - root` (或者简写为 `su -`)](#2. 完美的灵魂夺舍:
su - root(或者简写为su -)) - [3. 神仙下凡与平民串门(Root 降级与其他转换)](#3. 神仙下凡与平民串门(Root 降级与其他转换))
- [⚠️ `su` 的最大痛点:密码危机](#⚠️
su的最大痛点:密码危机)
- [1. 不彻底的变身:`su root` (或者直接敲 `su`)](#1. 不彻底的变身:
- [第二招:尚方宝剑 ------ `sudo` (Superuser DO)](#第二招:尚方宝剑 ——
sudo(Superuser DO)) -
- [1. 它是如何运作的?(白名单机制)](#1. 它是如何运作的?(白名单机制))
- [2. 实战用法](#2. 实战用法)
- [2.1 `sudo -u`:指定以谁的身份执行](#2.1
sudo -u:指定以谁的身份执行) - [3. 为什么企业里全都在用 `sudo`?](#3. 为什么企业里全都在用
sudo?)
- 总结:后端开发的黄金生存法则
- [第一招:灵魂夺舍 ------ `su` (Switch User)](#第一招:灵魂夺舍 ——
- 补充:终端的"俄罗斯套娃"
-
- [1. 终端的"俄罗斯套娃"](#1. 终端的“俄罗斯套娃”)
- [2. 如果再敲一次 `exit` 会怎样?](#2. 如果再敲一次
exit会怎样?)
- [补充:怎么在 /etc/sudoers里面添加用户?](#补充:怎么在 /etc/sudoers里面添加用户?)
-
- [🚨 绝对警告:永远不要直接 `vim /etc/sudoers`](#🚨 绝对警告:永远不要直接
vim /etc/sudoers) - [实战:如何赋予小李 `sudo` 权限?](#实战:如何赋予小李
sudo权限?) - 验证:测试尚方宝剑是否生效
- [🚨 绝对警告:永远不要直接 `vim /etc/sudoers`](#🚨 绝对警告:永远不要直接
- [2) 动态变脸:UGO 身份匹配游戏 (Role)](#2) 动态变脸:UGO 身份匹配游戏 (Role))
-
- [第一问:你是这房子的主人吗?(User - `u`)](#第一问:你是这房子的主人吗?(User -
u)) - [第二问:你是主人家属/团队的吗?(Group - `g`)](#第二问:你是主人家属/团队的吗?(Group -
g)) - [第三问:原来你是个路人!(Other - `o`)](#第三问:原来你是个路人!(Other -
o))
- [第一问:你是这房子的主人吗?(User - `u`)](#第一问:你是这房子的主人吗?(User -
- 3)公式右半边:文件属性(这栋房子挂着什么锁?)
-
- [锁的三个孔位(`rwx` 到底能干嘛?)](#锁的三个孔位(
rwx到底能干嘛?)) - [深入剖析 Group(家人/团队):主组与附加组](#深入剖析 Group(家人/团队):主组与附加组)
- [锁的三个孔位(`rwx` 到底能干嘛?)](#锁的三个孔位(
- 补充:完整流程
-
- [一、 关于"三把锁"(U、G、O):绝对不是同时开!而是"只开一把"](#一、 关于“三把锁”(U、G、O):绝对不是同时开!而是“只开一把”)
- [二、 关于锁上的"三个孔"(r、w、x):独立开关,各取所需](#二、 关于锁上的“三个孔”(r、w、x):独立开关,各取所需)
- 总结提炼
- [4) 如何看懂安保报告(`ls -l`)](#4) 如何看懂安保报告(
ls -l)) -
- [1. 红色箭头指示:文件类型(第 1 个字符)](#1. 红色箭头指示:文件类型(第 1 个字符))
- [2. 绿色框区域:三把权限锁(第 2 ~ 10 个字符)](#2. 绿色框区域:三把权限锁(第 2 ~ 10 个字符))
- [3. 蓝色框区域:拥有者 / 房主 (User)](#3. 蓝色框区域:拥有者 / 房主 (User))
- [4. 黄色框区域:所属组 / 帮派 (Group)](#4. 黄色框区域:所属组 / 帮派 (Group))
- 5)权限的表示方法及修改技巧。
-
- [一、 权限的表示方法:两套"编码"系统](#一、 权限的表示方法:两套“编码”系统)
-
- [1. 符号表示法(`ls -l` 的输出)](#1. 符号表示法(
ls -l的输出)) - [2. 八进制数字表示法(最快的心算法)](#2. 八进制数字表示法(最快的心算法))
- [1. 符号表示法(`ls -l` 的输出)](#1. 符号表示法(
- [二、 如何修改权限:`chmod` 的两派心法](#二、 如何修改权限:
chmod的两派心法) -
- [1. 字母派:精准微调](#1. 字母派:精准微调)
- [2. 数字派:一步到位](#2. 数字派:一步到位)
- [3.群攻技能:递归修改(-R 参数)](#3.群攻技能:递归修改(-R 参数))
- [谁有资格执行 chmod,取决于这个文件/目录本身的属主是谁。](#谁有资格执行 chmod,取决于这个文件/目录本身的属主是谁。)
- [三、 终极补丁:修改身份归属(`chown` / `chgrp`)](#三、 终极补丁:修改身份归属(
chown/chgrp)) -
- [1. `chown` (Change Owner):强制过户房产证](#1.
chown(Change Owner):强制过户房产证) - [2. `chgrp` (Change Group):修改帮派/户口本](#2.
chgrp(Change Group):修改帮派/户口本) - [3. 👑 职场高频大招:`chown` 的"一刀切"神技与 `-R` 参数](#3. 👑 职场高频大招:
chown的“一刀切”神技与-R参数) - [💡 终极排障口诀](#💡 终极排障口诀)
- [1. `chown` (Change Owner):强制过户房产证](#1.
- [补充章节:Linux 用户组管理(创建组与添加成员)](#补充章节:Linux 用户组管理(创建组与添加成员))
-
- [1. 如何创建组(groupadd)](#1. 如何创建组(groupadd))
- [2. 如何往组里面添加成员(usermod / gpasswd)](#2. 如何往组里面添加成员(usermod / gpasswd))
- [3. 如何查看组里的成员](#3. 如何查看组里的成员)
- [4. ⚠️ 至关重要的"生效时机"(新手极易踩坑)](#4. ⚠️ 至关重要的“生效时机”(新手极易踩坑))
- [5. 主要组(Primary) vs 附加组(Supplementary)------ 小科普](#5. 主要组(Primary) vs 附加组(Supplementary)—— 小科普)
- [6. 额外高阶技巧:批量添加或删除](#6. 额外高阶技巧:批量添加或删除)
- [补充: 村长办公室的"三大绝密档案"](#补充: 村长办公室的“三大绝密档案”)
-
- [1. 户籍花名册:`/etc/passwd`](#1. 户籍花名册:
/etc/passwd) - [2. 密码保险箱:`/etc/shadow`](#2. 密码保险箱:
/etc/shadow) - [3. 帮派名册:`/etc/group`](#3. 帮派名册:
/etc/group)
- [1. 户籍花名册:`/etc/passwd`](#1. 户籍花名册:
- [补充: 村长必学的 5 大实战指令](#补充: 村长必学的 5 大实战指令)
-
- [1. 添加新用户:`useradd`](#1. 添加新用户:
useradd) - [2. 设置/修改密码:`passwd`](#2. 设置/修改密码:
passwd) - [3. 修改已有用户属性:`usermod` 🌟(最高频)](#3. 修改已有用户属性:
usermod🌟(最高频)) - [4. 删除用户:`userdel`](#4. 删除用户:
userdel) - [5. 查看我是谁:`id`](#5. 查看我是谁:
id)
- [1. 添加新用户:`useradd`](#1. 添加新用户:
- 补充:文件能被执行的前提
-
- [第一门票:物理属性(文件的 `x` 权限)](#第一门票:物理属性(文件的
x权限)) - 第二门票:内容逻辑(它真的是个"可执行"的玩意吗?)
- [💡 核心流程:两道关卡缺一不可](#💡 核心流程:两道关卡缺一不可)
- 一个经典的"翻车"场景
- [第一门票:物理属性(文件的 `x` 权限)](#第一门票:物理属性(文件的
- [补充:`file` 指令](#补充:
file指令) -
- [1. `file` 指令的工作原理](#1.
file指令的工作原理) - [2. 基本用法与实战案例](#2. 基本用法与实战案例)
- [3. 常用高阶参数选项](#3. 常用高阶参数选项)
- [1. `file` 指令的工作原理](#1.
- 三)目录权限
-
- 补充:文件的内容是详细数据,目录的内容是不是就是里面所包含的文件的属性?
-
- [1. 目录的真正内容:只有"名字"和"身份证号"](#1. 目录的真正内容:只有“名字”和“身份证号”)
- [2. 文件的属性存放在哪里?------ Inode (索引节点)](#2. 文件的属性存放在哪里?—— Inode (索引节点))
- [3. 生动的类比:电话簿与警察局档案](#3. 生动的类比:电话簿与警察局档案)
- [4. 为什么 Linux 要进行这样"繁琐"的分离设计?](#4. 为什么 Linux 要进行这样“繁琐”的分离设计?)
- [1. 目录权限的本质:r、w、x 到底代表什么?](#1. 目录权限的本质:r、w、x 到底代表什么?)
- [2. 用户身份的三个维度(U、G、O)](#2. 用户身份的三个维度(U、G、O))
- [3. 进入目录需要什么权限](#3. 进入目录需要什么权限)
-
- [1) 核心结论:穿透力决定一切](#1) 核心结论:穿透力决定一切)
- [2) 极端场景推演(彻底弄懂 r、w、x 的相互依存)](#2) 极端场景推演(彻底弄懂 r、w、x 的相互依存))
-
- [场景一:只有 `r`,没有 `x`(权限:400,即 r--)------ "隔着毛玻璃看画"](#场景一:只有
r,没有x(权限:400,即 r--)—— “隔着毛玻璃看画”) - [场景二:只有 `w`,没有 `x`(权限:200,即 -w-)------ "废纸一张的修改权"](#场景二:只有
w,没有x(权限:200,即 -w-)—— “废纸一张的修改权”) - [场景三:作为对比,如果只有 `x`,没有 `r` 和 `w`(权限:100,即 --x)------ "盲盒模式 / 投递箱"](#场景三:作为对比,如果只有
x,没有r和w(权限:100,即 --x)—— “盲盒模式 / 投递箱”)
- [场景一:只有 `r`,没有 `x`(权限:400,即 r--)------ "隔着毛玻璃看画"](#场景一:只有
- 3.)最佳实践总结
- 4.Linux的权限掩码
-
- [1)什么是权限掩码 (umask)?](#1)什么是权限掩码 (umask)?)
- [2) 底层计算逻辑:绝不是简单的减法,而是位运算](#2) 底层计算逻辑:绝不是简单的减法,而是位运算)
- [3) 系统默认的 umask 设置](#3) 系统默认的 umask 设置)
- [4)如何查看与修改 umask](#4)如何查看与修改 umask)
- [5 目录的高阶权限:Sticky Bit (粘滞位 / 保护位)](#5 目录的高阶权限:Sticky Bit (粘滞位 / 保护位))
-
- [1) 痛点场景重现:共享目录的"黑暗森林"法则](#1) 痛点场景重现:共享目录的“黑暗森林”法则)
- 2)粘滞位的核心机制:权限的"精准收缩"
- 3) 表现形式:底层细节里的 `t` 与 `T` 表现形式:底层细节里的
t与T) - 4) 实操指令演示 实操指令演示)
- [补充: `chmod +x` 到底代表什么?](#补充:
chmod +x到底代表什么?) -
- [1. 平时用起来,记住这一句就够了](#1. 平时用起来,记住这一句就够了)
- [2. 为什么官方文档说它"不等于" `a+x`?(技术细节)](#2. 为什么官方文档说它“不等于”
a+x?(技术细节)) - [3. 什么时候 `chmod +x` 真的会"失灵"?(极少数情况)](#3. 什么时候
chmod +x真的会“失灵”?(极少数情况)) - 一句话终极总结(背下来就行)
- [补充: 两个普通用户如何进入到对方的家目录下](#补充: 两个普通用户如何进入到对方的家目录下)
第四章:Linux权限的概念:从底层逻辑到阶级跃迁
如果你刚从 Windows 切换到 Linux,最让你崩溃的,大概率是这行刺眼的红字:
Permission denied(权限被拒绝)。
你想建个文件?拒绝!你想装个软件?拒绝!你想进个目录?还是拒绝!
为什么 Windows 买来就能随便用,而 Linux 却处处设卡、森严得像个军事基地?这其实源于 Linux 诞生之初的"基因"。
一) 为什么我们需要权限?(Linux 的"合租房"哲学)
1. 天生的"多用户"基因(合租房逻辑)
Windows 早期是设计给"个人电脑(PC)"用的,一台电脑通常就你一个人用,你想拆家也没人管你。
但 Linux 继承了 UNIX/类 UNIX 系统的多用户、多任务 思想,并且后来广泛应用于服务器。一台大型服务器上,可能同时有大量用户或程序 登录、运行和共享系统资源(比如咱们的 Linux 村)。
如果没有权限系统,张三不小心敲错命令删了李四的代码,或者窃取了王五的数据库密码,整个服务器就变成了没有王法的"黑暗森林"。权限系统的存在,就是为了让几千人在"合租房"里各自安好,互不干涉。
2. 极致的防毒与隔离机制(防爆舱)
为什么大家都说 Linux 很少中病毒?很大程度上就是因为权限机制。
在 Linux 里,如果你以普通用户(小李)身份运行了恶意程序,那么在没有额外提权漏洞或错误授权的情况下,这个程序通常也只能拥有小李当前具备的权限,不能随意修改只有 root 才能操作的系统核心文件。权限系统就像是船舱里的"防水隔断",尽量把破坏限制在当前用户能够访问的范围内。
3. 保护"瞎子"内核(防止自毁)
我们之前说过,内核(如花)是极其强大但又盲目的,她只负责执行。如果没有权限这道门禁,任何一个不懂行的用户敲下格式化硬盘的命令,内核都会照做。权限系统其实是给人类加了一道"安全锁",防止人类因为愚蠢或手误摧毁系统本身。
如果用最通俗的一句话来定义:Linux 的权限,就是操作系统底层的"私人财产保护法"和"公共安全门禁系统"。
因此,Linux 引入了一套极其严密的权限管理系统 。一句话概括:它明确规定了"谁(Who)",能对"什么文件/目录(Where)",进行"什么样(What)"的操作。
linux同时会有多个用户进行操作,普通用户和root用户,权限的本质是为了更好的进行用户管理
二) 权限=人+文件属性
欢迎来到 Linux 村。
在真正动手敲打那些冰冷的命令行之前,我们需要在脑海中建立一个至高无上的核心公式:
权限 = 人 + 文件属性
遇到任何 Permission denied(权限拒绝)的报错,不要慌,更不要盲目去改代码。你只需要像福尔摩斯一样,冷静地把这个公式拆解开,分别去查明左边的"人"是谁,以及右边的"属性"是什么。
我们就先来彻底搞懂公式的左半边:在 Linux 村里,你到底是谁?
1) 绝对阶级:Linux 村的三大居民类型 (User)
在现实世界里,你是坐在电脑前的一个具体的"人"。但在 Linux 系统的眼里,你是被严格划分阶级的"账号(User)"。系统只认账号,不认活人。
Linux 村里只住着三类人:
1. 村长:Root(超级管理员)
-
地位: 拥有系统中的最高管理权限。
-
身份标识: 它的 UID(用户 ID)永远是
0。 -
特点: 拥有系统中最高级别的管理权限。 对传统的
rwx自主访问控制(DAC)而言,root 通常可以绕过普通用户受到的大多数读写权限检查;但 root 也并不是"无视系统中的一切限制",仍可能受到只读文件系统、特殊文件属性、安全模块等机制约束。 -
危险性: 极高。如果以 root 身份误执行高危删除、覆盖或权限修改命令,可能严重破坏整个系统。因此,日常生活中,我们不建议长期以 root 身份进行普通操作。
-
终端特征: 当你以 root 身份登录时,命令行提示符的结尾会变成一个霸气的井号
#。例如:
[root@localhost ~]# -
高危警告 ⚠️: root 身份下的误操作可能造成系统级破坏。现代 GNU
rm通常对直接递归删除根目录/有保护机制,但类似的高危删除命令、绕过保护后的操作或对其他关键目录的误删,仍然可能让系统无法正常工作。
2. 平民:普通用户(如 xiaoli, nanlin)
这是我们日常使用 Linux 时的标准身份。
-
地位: 处处受限的普通村民。这也是我们日常登录服务器时使用的身份。
-
身份标识: 他们的 UID 通常从
1000开始排起(比如 CentOS 7 中新建的第一个用户 UID 是 1000,第二个是 1001)。 -
特点: 他们通常主要在自己的"老家"(
/home/xiaoli/目录)里工作,并对自己拥有且权限允许的文件进行读写操作;但家目录里面也可能存在不属于自己的文件,因此并不是天然拥有"绝对控制权"。一旦走出家门,去到系统目录或者别人家门口,就必须严格遵守rwx等权限规则。想乱动?系统会无情地给你甩一句Permission denied。 -
终端特征: 当你以普通用户登录时,命令行提示符的结尾通常是一个温和的美元符号
$。例如:
[xiaoli@localhost ~]$
3. 隐形打工人:系统用户(如 mysql, nginx)
除了 root 和普通人,如果你打开系统的 /etc/passwd(用户花名册)文件看一眼,会发现里面有一大堆你从来没建过的奇怪名字,比如 bin, daemon, nginx, mysql, nobody 等。
- 地位: 没有灵魂的干饭机器,它们被称为 "系统用户"或"伪用户"
- 身份标识: UID 通常在 1~999 之间
- 特点: 这些账号通常用于运行后台服务进程。它们往往会被设置为不可交互登录 (例如使用
/usr/sbin/nologin或/bin/false),密码也通常被锁定;有些系统用户会有专用家目录或工作目录,因此不能简单理解为"都没有家目录"。 - 为什么需要他们? 假设村里的广播站(Nginx Web服务)是由村长(Root)负责运作的。如果有坏人(黑客)通过广播站的漏洞入侵了进来,坏人就会瞬间拥有村长的神权!为了安全,系统专门克隆了一个毫无实权的隐形人叫
nginx去管广播站。这样就算被黑客控制了,黑客也只能在这个破广播站里发呆,破坏不了村子的根基。
补充:root和普通用户之间的互相转换
su、su -、sudo、sudo -u 底层本质都是让某个进程以另一个用户的 UID/GID 身份运行:su 不指定用户时默认切到 root,验证成功后会启动一个 root 身份的新 Shell,但较多保留原用户环境;su - 同样默认切到 root,区别是还会模拟 root 重新登录,加载 root 的 HOME、PATH 等登录环境;sudo 命令 则不会把你当前的 Shell 变成 root,而是经过 sudo 权限检查后,仅临时创建一个 root 身份的进程来执行这一条命令,执行完你仍然是原用户;sudo -u 用户 命令 也是一样,只不过该命令不是以 root,而是以指定用户身份运行。所以简单记:su/su - 是"切过去,进入另一个用户的 Shell";sudo/sudo -u 是"人不切换,只让某条命令临时借用另一个用户的身份执行"。su = 切身份进入目标用户 Shell;su - = 切身份并完整加载目标用户登录环境;sudo = 当前用户不变,只让一条命令临时以 root 身份执行;sudo -u = 当前用户不变,只让一条命令临时以指定用户身份执行。
村长(root)通常可以绕过大多数传统 rwx 门禁,而村民(普通用户)则需要严格按照文件和目录权限进行操作。
但在真实的开发场景中,矛盾往往是这样产生的:你平时为了安全,必须以"平民"身份写代码;可当你需要安装一个 C++ 编译器、配置一下 Nginx 服务器,或者修改系统防火墙时,你又迫切需要"村长"的权力。
这就涉及到 Linux 管理中最核心的操作:用户身份的转换与提权(Privilege Escalation)。
在 Linux 中,实现阶级跃迁主要有两大绝招:su 和 sudo。它们虽然看起来像双胞胎,但背后的逻辑和应用场景却天差地别。
第一招:灵魂夺舍 ------ su (Switch User)
su 命令的核心作用是:以目标用户的身份启动一个新的 Shell 或执行命令,从而切换当前操作身份。
假设你现在是村民小李(xiaoli),你需要安装一个软件,于是你决定暂时变身为村长(root)。
这里有两个极易混淆的命令,也是全网 80% 的新手(甚至老手)经常踩坑的地方:
1. 不彻底的变身:su root (或者直接敲 su)
当你敲下 su root 并输入了村长的密码后,你的命令行提示符会从温和的 $ 变成霸气的 #。你确实拥有了最高权限。
- 核心区别: 这种切换不会像登录 Shell 那样完整初始化目标用户的登录环境 ,当前工作目录通常保持不变,并会保留当前环境中的很多内容(具体哪些变量会被保留或重设与
su的实现和系统配置有关)。 - 通俗理解: 就像是小李拿到了村长的"权力印章",但人还站在原来的位置(当前目录通常仍然是原目录),工具箱也没有完全换成村长登录时的那一套。
2. 完美的灵魂夺舍:su - root (或者简写为 su -)
注意中间那个不起眼的小减号 -,它代表 "Login Shell(完全登录)" 。
当你敲下 su - root 并输入村长(Root)的密码后:
- 你不仅拿到了权力印章,系统还会把你瞬间传送到村长办公室 (当前目录变成
/root)。 - 你的整套工具箱、环境变量,全部替换成了村长的专属配置。
- 这种方式更接近目标用户"重新登录一次"的环境,通常也是需要完整切换用户环境时更推荐的方式。
如何变回自己? 想要退出村长身份变回小李,只需敲入
exit或者按快捷键Ctrl + D。
3. 神仙下凡与平民串门(Root 降级与其他转换)
除了提权升仙,我们同样需要掌握如何从 Root "下凡"或在普通用户之间"串门":
- Root 切换为普通用户(神仙下凡): 当你是 root 状态时,如果想强行"附身"切换到系统里的任何一个普通村民(比如张三
zhangsan去测试代码),只需敲入su - zhangsan。核心特权:完全不需要输入张三的密码! 系统绝不会阻拦神仙下凡。 - 普通用户切换为普通用户(平民串门): 如果你是小李,想直接切换到张三而不经过 root,敲入
su - zhangsan。此时系统会严格要求你必须输入 张三(目标用户)的密码。平民之间互相串门,必须得到主人的钥匙。
⚠️ su 的最大痛点:密码危机
su 最大的问题在于,它要求你必须知道目标用户的密码!
如果你们公司有 10 个后端开发人员,每个人都需要偶尔提权装软件,难道要把最高机密的 Root 密码发给这 10 个人吗?一旦密码泄露,或者某个人离职前恶意删库(rm -rf /*),连是谁干的都查不出来!
为了解决这个职场灾难,Linux 推出了第二招。
第二招:尚方宝剑 ------ sudo (Superuser DO)
默认情况下,
sudo不指定-u时通常以 root 身份执行命令, 因此该命令新建文件的属主通常是 root,所属组通常也是目标用户(默认 root)的主组;不过目标目录的 SGID 等机制仍可能改变新文件的属组。使用sudo -u 用户名时则可以指定其他目标用户。
sudo 是现代 Linux 服务器管理中最优雅、最安全的提权方式。
它的核心逻辑不再是"把整个 Shell 长时间切换成村长",而是"你仍然从自己的账号发起命令,sudo 根据授权让这一条命令临时以目标用户(默认通常是 root)的身份执行"。
1. 它是如何运作的?(白名单机制)
村长(Root)手里有一个绝密的小本本,叫做 /etc/sudoers(权限白名单)。
只要村长提前把小李的名字写进了这个小本本里,小李就获得了使用尚方宝剑的资格。
2. 实战用法
当小李想要安装软件(比如 gcc)时,直接运行安装命令会被拒绝:
bash
[xiaoli@localhost ~]$ yum install gcc
# 报错:Permission denied (你没有权限)
此时,小李拔出尚方宝剑,在命令最前面加上 sudo:
bash
[xiaoli@localhost ~]$ sudo yum install gcc
# 系统提示:[sudo] password for xiaoli:
💡 核心重点来了:
在常见的默认 sudo 配置 下,此时系统要求输入的通常不是 Root 的密码,而是小李自己的密码 ;当然,管理员也可以通过 sudoers 修改认证方式,或者配置为免密。认证和授权通过后,这条命令会按照 sudoers 指定的目标用户身份执行;未指定 -u 时通常就是 root。
2.1 sudo -u:指定以谁的身份执行
sudo 还支持 sudo -u 用户名 命令 的形式,也就是并不一定非要以 root 身份执行:
bash
# 以 root 身份执行 useradd
sudo -u root /usr/sbin/useradd u2
# 也可以指定其他允许的目标用户
sudo -u 用户名 命令
如果不写 -u,sudo 默认通常以 root 身份执行。
sudo -u 普通用户 也需要配置权限。
sudo -u 普通用户 命令的意思不是"因为目标是普通用户,所以谁都能执行",而是:当前用户请求 sudo 允许自己以另一个指定用户的身份执行命令 。sudo仍然会检查/etc/sudoers或/etc/sudoers.d/,确认"当前用户有没有权力切换成这个目标用户并执行这条命令"。例如alice执行sudo -u bob command,并不会先变成 root,而是 sudo 在获得授权后直接让command以bob的 UID/GID 运行;但 alice → bob 这个切换行为本身仍然必须获得 sudo 授权 。如果你本来就是bob,直接执行command即可,没必要sudo -u bob。
3. 为什么企业里全都在用 sudo?
相比于 su,sudo 拥有三大碾压级优势:
- 更安全: 不需要向任何人泄露最高机密的 Root 密码,并且可以按命令进行授权。
- 精准授权(最小特权原则): 村长可以在小本本里精细规定:"小李的
sudo只能用来重启 Nginx 服务,不能用来删除文件"。而su是一给就给全部权限。 - 可追溯:
sudo通常会按系统和 sudoers 的日志配置记录命令调用信息(常见日志位置包括/var/log/secure、/var/log/auth.log或 systemd journal),因此比共享 Root 密码更便于审计和追踪。
注意:
sudo认证成功后通常会有一段认证缓存时间 ,在有效期内再次执行sudo可能不需要重新输入密码。具体时长由 sudoers 中的timestamp_timeout等配置决定,不同发行版和管理员配置可能不同,不能固定记成 15 分钟。
总结:后端开发的黄金生存法则
懂得了这两种转换逻辑后,在你以后的 C++ 后端开发或服务器运维生涯中,请把下面这两条原则刻在骨子里:
- 封印 Root 账号,拒绝直接登录:
在正规公司的生产服务器上,第一件事就是修改 SSH 配置文件(sshd_config),禁止 Root 账号直接远程登录 (PermitRootLogin no)。所有人必须先用普通账号登录服务器。 - 能用
sudo解决的,绝不用su -:
日常看日志、敲代码,就用普通账号。遇到需要提权的指令,养成敲sudo的习惯。su -会让你持续处于目标用户身份;而sudo更适合按命令临时授权。需要注意,sudo并不保证每次都重新输入密码,因为它可能存在认证缓存时间。

💡 看图速记口诀:
- 向上爬(变神仙) :要谁的命,就得有谁的密码 (
su - root要 root 密码;su - userB要 B 的密码)。 - 借神力(用大招) :证明你是你自己,用自己的密码 (
sudo)。 - 向下走(回凡间) :root 可以直接
su - 普通用户而无需目标用户密码;如果只是退出上一层su启动的 Shell,则使用exit。
补充:终端的"俄罗斯套娃"
为了让你彻底明白这背后的原理,我们需要理解 Linux 终端的 "俄罗斯套娃"逻辑 。
1. 终端的"俄罗斯套娃"
使用 su 进行身份切换时,并不是把原来的 Shell "抹除"了,而是通常由 su 启动目标用户的一个新 Shell(形成新的进程层级);原来的 Shell 仍然在下面等待。
我们来重演一下这个过程:
- 初始状态: 你以普通村民
xiaoli的身份登录了服务器。(此时你处于第一层套娃)。 - 变身神仙: 你敲入
su - root并输入了村长的密码。此时,系统并没有杀掉原来的xiaoliShell,而是启动了一个以 root 身份运行的新 Shell。(此时你处于第二层套娃,root 状态,但仍然使用同一个终端设备/终端窗口)。 - 下凡降级: 你在 root 状态下敲入了
exit或按了Ctrl + D。- 系统底层做了什么? 最外层的 root Shell 退出,控制权返回给下面仍在等待的
xiaoliShell。 - 结果: 你自然而然地露出了里面的第一层套娃,也就是变回了
xiaoli。
- 系统底层做了什么? 最外层的 root Shell 退出,控制权返回给下面仍在等待的
2. 如果再敲一次 exit 会怎样?
既然你已经变回了 xiaoli(第一层套娃),如果你这个时候再敲一次 exit,会发生什么?
- 它会让当前这个
xiaoliShell 退出。 - 最终结果: 如果它正是登录 Shell,那么你通常会注销当前登录会话;远程 SSH 会断开。图形终端窗口是否随之关闭,则取决于终端模拟器的设置。
场景 A: 小李 登录 ➡️ su - root 变成村长 ➡️ exit 销毁村长外壳 ➡️ 退回小李。
场景 B: root 登录 ➡️ su - 小李 变成小李 ➡️ exit 销毁小李外壳 ➡️ 退回 root。
回归"Linux 村"的比喻:
你(小李)用密码打开了村长办公室的门,走进去坐在了老板椅上(
su - root)。当你处理完事情,敲下
exit,就相当于你走出了村长办公室,并把门在身后重重地关上反锁了 。这时你站在走廊里(变回小李),如果你想再进去,推门是推不开的,你只能重新掏出钥匙(再输一次密码)开门。
补充:怎么在 /etc/sudoers里面添加用户?
把一个普通村民的名字写进"白名单(sudoers)",赋予他使用尚方宝剑的权力,这是村长(root)的专属特权。
在这个过程中,有一个全网无数新手痛哭流涕的致命天坑。为了让你安全地完成提权,我们分步骤来详细讲解。
🚨 绝对警告:永远不要直接 vim /etc/sudoers
直接用 vi 或 vim 编辑 /etc/sudoers 风险很高:如果写出语法错误,可能导致后续 sudo 无法正常解析配置。
更安全、推荐的姿势是:使用 visudo 命令。
visudo会以安全方式编辑 sudoers,并在退出前进行语法检查;发现错误时会给出提示并让你选择如何处理,从而显著降低把 sudo 配置改坏的风险。
实战:如何赋予小李 sudo 权限?
首先,你必须是 root 身份(或者你本身已经拥有了 sudo 权限)。
配置的方法分为两大流派,企业里通常强烈推荐第一种。
推荐流派:加入"特权帮派"(最优雅、最安全)
很多主流 Linux 发行版会在默认 sudoers 配置中授权一个"特权组"。只要该系统确实启用了对应规则,把小李加入这个组后通常就能获得 sudo 权限,无需再为这个用户单独增加一条 sudoers 规则。
usermod -aG wheel 用户 的作用是把这个用户加入 wheel 组,它修改的主要是用户/组数据库,比如 /etc/group,
不会直接把用户名写进 /etc/sudoers。
-
如果你用的是 CentOS / RedHat 系列:
这个特权组叫
wheel。bash将小李追加到 wheel 组 (-a 代表 append 追加,-G 代表群组) usermod -aG wheel xiaoli -
如果你用的是 Ubuntu / Debian 系列:
这个特权组就叫
sudo。bash将小李追加到 sudo 组 usermod -aG sudo xiaoli
搞定! 小李现在已经拥有完整的 sudo 权限了。这是企业运维中最标准的做法。
传统流派:手动修改白名单(适合精细化控制)
如果你不想把小李拉进群,就是想单独给他开绿灯,或者想给他设置"免密执行",你就需要手动改文件了。
第一步:敲下安全编辑命令
bash
visudo
(此时系统会打开一个类似 vim 的编辑界面。)
第二步:找到 Root 的配置行
在文件中往下翻,找到下面这行代码(大概在第 100 行左右):
text
root ALL=(ALL) ALL
第三步:在下面添加小李的名字
按键盘上的 i 键进入插入模式,在 root 那一行的下面,照猫画虎加上小李的配置。这里有三种给法,看你有多信任小李:
-
选项 A:常规授权(需要输小李自己的密码,推荐)
textroot ALL=(ALL) ALL xiaoli ALL=(ALL) ALL -
选项 B:极致信任(执行 sudo 时连密码都不用输,高危!通常只给自动化脚本用)
textroot ALL=(ALL) ALL xiaoli ALL=(ALL) NOPASSWD: ALL -
选项 C:精准限制(小李只能用 sudo 重启 Nginx,干别的都不行,极度安全)
textroot ALL=(ALL) ALL xiaoli ALL=(ALL) /usr/bin/systemctl restart nginx
第四步:保存并退出
按 Esc 键退出编辑模式,输入 :wq 然后按回车(和 vim 的操作一模一样 :q!不保存退出)。如果语法没问题,系统不会有任何提示就退出了;如果有错,它会拦住你。
验证:测试尚方宝剑是否生效
配置完之后,我们可以切回小李的账号测试一下。
bash
# 1. 切换到小李
su - xiaoli
# 2. 尝试看一眼只有 root 才能看的系统密码本(shadow)
cat /etc/shadow
# 结果:立刻报错 Permission denied
# 3. 拔出尚方宝剑!
sudo cat /etc/shadow
# 系统提示:[sudo] password for xiaoli:
# (此时输入小李的密码)
# 结果:成功看到乱码般的密码本!提权成功!
总结: 能用 usermod -aG 解决的,就不要去碰 /etc/sudoers 文件;如果非要改,死死记住 visudo 这个保命命令。
2) 动态变脸:UGO 身份匹配游戏 (Role)
ugo在权限访问的时候只会严格按照从左到右确认,也只会确认一次,确定好后不在改变
搞懂了你是平民还是村长后,接下来是最核心、也是新手最容易晕的环节:身份的动态转化。
在 Linux 的底层逻辑里,"你能不能碰这个文件",看的不是你叫什么名字,而是看你相对于这个文件,是什么角色。
当村民小李走到一栋房子(文件)门前想推门时,系统会按照 User -> Group -> Other 的逻辑确定他应使用哪一组传统权限:先判断是否是文件属主;不是属主时,再判断其有效组/附加组是否匹配文件属组;都不匹配时才使用 Other 权限。一旦身份类别确定,就不会因为该类别权限不足而继续"降级"尝试后面的权限。
第一问:你是这房子的主人吗?(User - u)
- 安保卫士掏出这栋房子的"房产证"(文件所有者)。
- 核对发现,房子就是小李自己建的!
- 匹配结果: 身份确认为 房主 (User /
u)。 - 立刻放行: 去查看房主专用锁的权限,不再进行后续提问。
第二问:你是主人家属/团队的吗?(Group - g)
- 假设这房子是老王建的,小李在第一问被淘汰了。安保卫士接着掏出户口本(用户组)。
- 核对发现,小李虽然不是房主,但他和房主老王同属于
dev_team(开发组)这个帮派。 - 匹配结果: 身份确认为 家人/队友 (Group /
g)。 - 立刻放行: 去查看团队专用锁的权限,不再进行后续提问。
第三问:原来你是个路人!(Other - o)
- 假设房子是村东头赵大爷建的,小李既不是房主,也不跟赵大爷在同一个帮派。
- 匹配结果: 身份确认为 陌生路人 (Other /
o)。 - 最后判定: 只能去查看针对路人设定的那把锁,通常也是最严苛的一把锁。
传统 rwx 权限主要用于限制普通用户;root 通常可以绕过大多数普通 DAC 读写检查,但并不代表它能无视系统中的所有安全机制。也正因为 root 权限极高,一旦误操作,影响范围往往远大于普通用户。
💡 核心顿悟:在整个 Linux 村里,小李永远是小李。
但当他面对"小李的日记本"时,他是 User ;
当他面对"开发组共享代码"时,他是 Group ;
当他面对"村长保险柜"时,他是 Other 。
你的角色,是随着你面对的文件不同,而动态改变的!
3)公式右半边:文件属性(这栋房子挂着什么锁?)
当你被系统贴上身份标签(U、G 或 O)后,系统紧接着就会去查看这栋房子(文件或目录)自带的属性配置单。
在 Linux 村里,任何一个文件诞生时,门上都会被死死焊上三把物理锁,严格对应三种身份:
- 第一把:给 房主 (User -
u) 的专属锁。 - 第二把:给 家人/团队 (Group -
g) 的共享锁。 - 第三把:给 路人 (Other -
o) 的防盗锁。
💡 注记: 你可能听说过
a(All - 所有人),请注意,文件上并没有第四把叫作a的锁。a只是村长在批量改门禁时用的"快捷口令"(代表同时修改 UGO 三把锁)。
锁的三个孔位(rwx 到底能干嘛?)
每把锁里面,都精确雕刻了三个孔位,分别控制三种行为(也就是我们熟知的 rwx 属性)。
这里是许多新手都会栽跟头的地方:同样的 rwx,放在"普通文件"和"目录(文件夹)"上,含义截然不同!
| 字符与数字代号 | 本质动作 | 面对"普通文件"(如日记本、脚本) | 面对"目录/文件夹"(如一个房间) ⚠️高能预警 |
|---|---|---|---|
r (Read) 数字: 4 |
看 | 阅读内容: 能用 cat 或 vim 看到文件里面写了什么。 |
查看列表: 能用 ls 看到这个房间里摆了哪些东西(文件列表)。 |
w (Write) 数字: 2 |
改 | 修改内容: 能改写、追加甚至清空文件的内容。 | 改变结构: 能在这个房间里新建、删除、重命名文件! |
x (Execute) 数字: 1 |
动 | 当成程序跑: 能把文件当作可执行脚本跑起来(比如 .sh、编译后的 C++ 程序)。 |
跨过门槛: 能用 cd 命令进入这个房间! |
⛔ 新手必读的终极避坑指南:目录的
x权限!很多新手在操作目录时,觉得只要拥有了
r(读)和w(写)权限,就能在里面建文件了。大错特错!在 Linux 的底层逻辑里,如果你没有一个目录的
x权限,这就意味着 "这扇门你推不开" 。你连门都进不去,拥有再多的r(在门外拿望远镜看)和w(隔着墙扔砖头)也是废纸一张!结论:要想让一个目录正常可用,通常必须赋予它
x权限。
深入剖析 Group(家人/团队):主组与附加组
讲到这里,你可能会产生一个疑问:系统在匹配第二把锁(Group 锁)的时候,它是怎么判断我到底是不是属于这个"团队"的呢?
这就涉及到了 Linux 用户管理中必考的核心概念:群组(Group)的双重身份。在 Linux 里,一个人的群组关系严格分为两种:
-
娘家 ------ 主组(Primary Group)
在很多 Linux 发行版的默认配置中,新建账号
xiaoli时会同时建立一个同名的私有组xiaoli,并把它作为这个用户的主组;具体是否自动创建同名组由发行版和useradd配置决定。主组的重要作用是: 进程通常以用户的主组作为有效组,因此新建文件的属组通常也是这个有效组;如果父目录设置了 SGID 等机制,新文件则可能继承父目录的属组。
-
帮派 ------ 附加组(Supplementary Group)
小李后来在村里找了份工作,加入了开发团队。于是村长(Root)把小李拉进了
dev_team(开发组)和docker(容器组)。这两个就是小李的附加组 。附加组的作用是: 小李可以同时拥有多个附加组的钥匙。以后只要有文件的 Group 锁上写着
dev_team或docker,小李就能用他附加组的身份,合法开启这把锁!
补充:完整流程
一、 关于"三把锁"(U、G、O):绝对不是同时开!而是"只开一把"
在这三把锁面前,你不需要、也不能同时打开它们。 系统的安保卫士有着极度死板的 "唯一匹配原则(一锤子买卖)":
- 按顺序查身份: 卫士会严格按照
User(房主) -> Group(家人) -> Other(路人)的顺序查你的户口。 - 一旦命中,立刻锁定: 只要你在某一步被确认了身份,卫士就会直接把对应的那把锁扔给你,并且当场把另外两把锁砸碎(忽略)!
💡 举个极端但非常经典的"坑人"例子:
假设村长建了一个文件,权限设成了这样:--- --- rwx (房主:焊死;家人:焊死;路人:满配)。
- 如果是路人小李来: 卫士查到小李是
Other,把最后一把rwx的锁交给他,小李开开心心地读写执行。 - 如果是普通用户房主本人来: 卫士查到他是
User,只检查第一组---。房主抗议说:"凭什么路人都能看,我是房主反而不能看?" - 卫士的回答是无情的: "抱歉,既然你是房主,你就只能用房主这把锁。这把锁焊死了,你就进不去。我不管路人的锁是什么样。"
结论: 三把锁之间是互斥 的,系统只认符合你身份的那唯一一把锁。
二、 关于锁上的"三个孔"(r、w、x):独立开关,各取所需
当你拿到属于你的那把锁之后,锁上的 r(读)、w(写)、x(执行/进入)这三个孔,不是串联的,而是并联的"独立开关"。
只要其中一个孔是开的,你就能执行它对应的单一动作。
- 只有
r开着 (r--): 你可以趴在窗户上看(cat 读取内容),但你想塞垃圾进去(写入)或者推门进去(执行),就会被电击(Permission denied)。 - 只有
w开着 (-w-): 这是一个非常奇葩但合法的权限。你可以闭着眼睛往房间里扔东西(追加内容),但你不能看里面原来有什么。 - 只有
x开着 (--x): 你可以按遥控器让房间里的机器跑起来(执行程序),但你不知道机器的代码是怎么写的。
⚠️ 唯一的致命关联(目录大坑再次强调):
刚才说的"独立开关"对普通文件是 100% 成立的。
但是面对"目录(房间)"时,
x孔变成了物理大门! > 只要x没有开,你就进不去房间。此时就算你手里的r和w开关都是亮着的,你也只能站在院墙外面干瞪眼。
总结提炼
你可以把这套系统想象成去银行金库:
- 看人给锁: 银行保安先核实你是行长、员工还是客户。确认身份后,只把你带到属于你那台专属 ATM 机前(只开属于你的那把锁)。
- 按孔办事: 这台 ATM 机上有三个按钮(存钱
w、查余额r、转账x)。哪个按钮亮着,你就能点哪个按钮办理单项业务(孔位独立工作)。
4) 如何看懂安保报告(ls -l)

当你在终端敲下 ls -l 时,系统会吐出一大段看起来像天书的代码。别慌,这其实就是每个文件身上挂着的"安保配置单"。
结合上面的图解,我们挑出其中具有代表性的一行(比如 .bashrc 文件),像切香肠一样,把它一块一块地切开来剖析:
text
-rw-r--r-- 1 root root 3106 Oct 15 2021 .bashrc
对照着图中的颜色框线,我们从左到右依次拆解这四大核心模块:
1. 红色箭头指示:文件类型(第 1 个字符)
大门安保首先要确认的,是你面对的到底是个什么"物件"。
-(横杠): 代表这是个普通文件(比如文本、压缩包、代码文件)。d(directory): 代表这是个目录/文件夹 。(你可以看到图中上面带有drwx...的,都是蓝色的文件夹)。l(link): 代表符号链接/软链接。b(block): 代表块设备文件(如磁盘等)。c(character): 代表字符设备文件(如终端等)。p(pipe): 代表命名管道文件。s(socket): 代表套接字文件。
2. 绿色框区域:三把权限锁(第 2 ~ 10 个字符)
紧跟在文件类型后面的这 9 个字符(如 rw-r--r--),就是我们上一节苦苦钻研的 rwx 物理锁 。
系统会极其死板地把它分为三组,每组 3 个字符,严格对应三种身份:
- 前三位
rw-: 给房主(User)的锁。能读(r)、能写(w),不能执行(-)。 - 中三位
r--: 给家人(Group)的锁。只能读(r)。 - 后三位
r--: 给路人(Other)的锁。只能读(r)。
3. 蓝色框区域:拥有者 / 房主 (User)
跳过中间那个代表硬链接数量的数字(通常初学者不用管),我们来到了图中的蓝色框:root。
- 这就是这栋房子的"房产证"上写的名字。
- 联动逻辑: 这里的
root用户,对应的就是绿框里的第一把锁(前三位rw-)。
4. 黄色框区域:所属组 / 帮派 (Group)
紧挨着房主名字的,是图中的黄色框:root(注意,Linux 中有很多用户名和组名是同名的)。
- 这就是这栋房子所属的"帮派/户口本"名称。
- 联动逻辑: 只要你在这个
root组里(哪怕你不是房主本人),你就能享受绿框里的第二把锁(中三位r--)的权限。
(至于后面剩下的内容,就比较简单了:分别是文件的大小(字节)、最后一次修改的日期时间,以及文件的具体名称。)
5)权限的表示方法及修改技巧。
除了文件拥有者就只有root能修改文件权限,其他用户修改必须sudo或者提升为root.
一、 权限的表示方法:两套"编码"系统
在 Linux 中,权限主要有两种表达方式:符号表示法(给人类看)和八进制数字表示法(给机器算)。
1. 符号表示法(ls -l 的输出)
当你输入 ls -l 时,看到的那串字符(如 -rwxr-xr--)就是符号表示法。正如你之前看到的图解,我们将它分为 4 个部分
2. 八进制数字表示法(最快的心算法)
在修改权限时,老鸟们更喜欢用数字。这是基于一套简单的权重相加逻辑:
r(Read) = 4w(Write) = 2x(Execute) = 1-(无权限) = 0
计算逻辑: 每一组(U、G、O)的三个孔位数字相加。
- 7 (4+2+1) =
rwx(满配权限) - 6 (4+2+0) =
rw-(读写,常用于.cpp源码文件) - 5 (4+0+1) =
r-x(读和进入,常用于编译后的 C++ 程序或目录) - 4 (4+0+0) =
r--(纯只读)
例子: chmod 754 意味着:房主全开(7),家人能读能进(5),路人只能看一眼(4)。
777 是八进制数:Linux 权限用三位八进制数表示,分别对应所有者、所属组、其他用户的权限。
二、 如何修改权限:chmod 的两派心法
chmod (change mode) 是修改传统 rwx 模式权限最常用、最核心的指令。 它同样分为两个流派:
1. 字母派:精准微调
适用于你不想计算数字,只想针对某个人加减某个权限的情况。
- 公式:
chmod [身份] [操作符] [权限] [文件名] - 身份:
u(房主),g(组),o(路人),a(所有人)。 - 操作符:
+(增加),-(取消),=(唯一设定)。
实战场景:
- 你写了一个
test.sh脚本却跑不起来?chmod a+x test.sh(给所有人加执行权)。 - 不想让组里的其他人改你的
main.cpp?chmod g-w main.cpp(剥夺组的写权限)。 - 同类示例还有:
chmod u+w /home/abc.txt、chmod o-x /home/abc.txt、chmod a=x /home/abc.txt。
2. 数字派:一步到位
适用于你清楚地知道最终三位身份分别要什么权限。
- 公式:
chmod [三个数字] [文件名]
实战场景:
- 设置一个只有你自己能读写的私密文档:
chmod 600 my_secret.txt。 - 设置一个标准的 C++ 编译后程序:
chmod 755 a.out。 - 其他三位八进制示例:
chmod 664 /home/abc.txt、chmod 640 /home/abc.txt。
3.群攻技能:递归修改(-R 参数)
有时候,你从网上下载了一个开源的 C++ 框架,解压出来发现里面有一千个文件和几百个文件夹,权限全乱了。你不可能挨个去改。
这时候你需要加上大写字母 -R (Recursive,递归)。
bash
将 src 目录,以及该目录下面嵌套的所有子目录、所有文件,全部一键改成 755!
chmod -R 755 src/
💥 毁灭级避坑警告:
绝对不要在 Linux 的根目录 / 或者系统核心目录 /etc, /usr 下使用 chmod -R。
曾经有新手敲下 sudo chmod -R 777 /,这会导致系统所有的安全防护瞬间蒸发,很多需要严格权限验证的服务(如 SSH 远程登录)会当场死机,系统直接报废重装!
谁有资格执行 chmod,取决于这个文件/目录本身的属主是谁。
- 文件属主:可以修改自己文件的权限
- 目录属主:可以修改自己目录的权限
- root:可以修改几乎任何文件/目录的权限
- 普通用户如果不是该文件/目录的属主,即使对它有 rwx 权限,通常也不能执行 chmod 修改权限
chmod 的字母和数字方式都能修改文件或目录的权限;但通常只有该文件/目录的属主和 root 才能修改它的权限。
三、 终极补丁:修改身份归属(chown / chgrp)
有时候,你会遇到一种极其诡异的情况:权限明明开着,但你就是打不开。
经典案发场景: 村长(Root)帮你下载了一个 C++ 编译工具包,顺手放在了你(小李 xiaoli)的院子(家目录)里。结果你去运行的时候,系统却提示 Permission denied。
破案: 因为这个工具包是村长下载的,它的"房产证(拥有者)"上写的是 Root 的名字!小李在自己的院子里,面对这个工具包,竟然被系统判定为了"路人(Other)"。
如果小李试图去敲 chmod 给自己加权限(比如 chmod u+x tools.tar.gz),系统会直接报错:Permission denied。为什么? 因为 chmod 虽然叫修改权限,但只有 房主(User) 或 root 才有资格调用这个功能。小李作为路人,连锁芯都碰不到,他根本没有权限去调用 chmod 这个命令来修改这个文件。这时候,光改锁(chmod)是没用的,我们需要直接改变文件的归属权。
1. chown (Change Owner):强制过户房产证
chown 的作用极其直接:把文件或目录的"拥有者"强行换成另一个人。
- 功能: 修改文件或目录的拥有者。
- 格式:
chown [参数] 新房主名字 文件名 - 示例:
chown user1 f1;递归修改可写作chown -R user1 filegroup1。
💻 实战演练:
村长把下载好的工具包 tools.tar.gz 真正地交给小李,让他成为合法的房主:
bash
sudo chown xiaoli tools.tar.gz
执行完之后,再去 ls -l 看安保报告,你会发现第三列的名字从 root 变成了 xiaoli。此时,小李就可以光明正大地使用"User 锁"对应的权限了。
⛔ 必考核心警示:为什么普通人不能随便过户?
细心的你可能发现了,上面的命令加了
sudo(借用村长的特权)。
在 Linux 中,普通用户绝对无法使用 chown 把自己的文件送给别人!哪怕这文件是你自己亲手建的!为什么这么霸道? 假设村里规定每个人的硬盘空间最多只能用 100GB(磁盘配额)。如果小李可以随便过户,他就可以建一个 99GB 的超级垃圾文件,然后偷偷
chown甩锅给老王。老王的硬盘瞬间爆满,导致系统崩溃。为了防止这种"栽赃嫁祸",Linux 铁律规定:只有 Root(村长)才有权力变更房产证。
2. chgrp (Change Group):修改帮派/户口本
chgrp 的作用是修改文件挂靠的"所属组"。
- 功能: 修改文件或目录的所属组。
- 格式:
chgrp [参数] 新组名 文件名 - 常用选项:
-R,递归修改目录及其内部文件/子目录的所属组。 - 示例:
chgrp users /abc/f2。
💻 实战演练:
小李写了一个绝密的 C++ 算法文件 algorithm.cpp。默认情况下,这个文件的所属组是小李的私人主组(xiaoli)。现在项目要联调了,他需要让 dev_team 开发组的其他兄弟也能一起改代码。
bash
第一步:把文件的帮派属性改为开发组
sudo chgrp dev_team algorithm.cpp
第二步:(配合前面学的知识)给开发组的家人开通 rw 权限
chmod g+rw algorithm.cpp
搞定!只要是户口本上写着属于 dev_team 的兄弟,现在都能共同开发这个文件了。
3. 👑 职场高频大招:chown 的"一刀切"神技与 -R 参数
在真实的后端服务器部署中,老程序员极少会分开去敲 chown 和 chgrp,因为太麻烦了。
chown 命令其实提供了一个 "房主和帮派一起换" 的终极组合技,外加一个极具杀伤力的群攻参数 -R (递归 Recursive)。
- 黄金组合语法(中间用冒号
:分隔):chown -R [新房主]:[新帮派] [目录名]
💻 实战演练(部署网站代码):
小李把本地写好的 C++ 项目上传到了服务器的 /opt/my_project/ 目录下。里面有几百个嵌套的子文件夹和源码。因为是用 root 账号上传的,里面所有的文件都归 root 所有。
现在,小李需要一次性把整个项目的心血,全部划归给自己和开发组。
bash
sudo chown -R xiaoli:dev_team /opt/my_project/
敲下回车的那一瞬间发生了什么?
不管这个目录下面嵌套了 10 层还是 100 层子目录,不管里面有几千个源码文件。它们的"房产证"全部瞬间被改成了 xiaoli,户口本全部盖上了 dev_team 的钢印!
💡 终极排障口诀
以后在 Linux 里遇到 Permission denied,请在脑海里默念这三步排查法:
- 先查户口(
ls -l):看看房产证和帮派是不是自己的名字。 - 人不对,先换人(
chown) :如果名字不对,立刻用sudo chown把归属权抢回来。 - 人对了,再换锁(
chmod) :确认归属权没问题了,再去看看rwx的孔位开没开对,用chmod补齐权限。
补充章节:Linux 用户组管理(创建组与添加成员)
在 Linux 中,组(Group) 用于集中管理一群用户的权限。比如,想让 a 文件能被开发部的所有同事读写,只需把文件所属组改为 dev,再把同事加入 dev 组即可。
1. 如何创建组(groupadd)
使用 groupadd 命令,需要 root 权限或 sudo。
bash
sudo groupadd 组名
示例 :创建一个名为 project_rw 的组。
bash
sudo groupadd project_rw
创建成功后,系统会在 /etc/group 文件中记录该组信息。你可以用 tail 验证:
bash
tail -n 5 /etc/group
2. 如何往组里面添加成员(usermod / gpasswd)
最常用且有两种 方法,强烈推荐方法一:
-
方法一:使用
usermod(修改用户附加组)语法:
sudo usermod -aG 组名 用户名重点 :必须带
-a(append)参数!如果只写-G不带a,会把用户从其他所有附加组中踢出,只保留这一个组。bash# 将用户 mnl 添加到 project_rw 组 sudo usermod -aG project_rw mnl -
方法二:使用
gpasswd(组管理员专用)语法:
sudo gpasswd -a 用户名 组名bashsudo gpasswd -a mnl project_rw这个方法不需要加
-a(它本身默认就是添加),相对更直观,不容易误操作。
3. 如何查看组里的成员
-
查看当前用户属于哪些组 :直接用
groups命令。bashgroups # 或指定查看某用户 groups mnl -
查看系统所有组及成员 :读取
/etc/group文件,或使用getent。bashgetent group project_rw输出格式为:
组名:密码占位符:GID:成员列表(逗号分隔)
4. ⚠️ 至关重要的"生效时机"(新手极易踩坑)
你执行 usermod 或 gpasswd 将用户加入组后,当前已经打开的终端会话(Shell)不会立刻生效!
- 如果你用
groups命令查看,发现新组已经显示出来了(因为读取了/etc/group),但实际权限并未生效。 - 解决方法(二选一) :
- 退出当前 SSH 会话,重新登录(最稳妥)。
- 在当前终端执行
newgrp 组名临时切换身份(仅影响当前终端,重启终端后仍需重新登录)。
只有重新登录后,新加入的组权限才会真正作用于你执行 chmod 等操作时。
5. 主要组(Primary) vs 附加组(Supplementary)------ 小科普
- 主要组(主组):创建用户时默认生成的同名组。用户新建文件时,文件默认属于这个组。
- 附加组(辅助组) :你用
usermod -aG添加的组。一个用户只能有一个主组,但可以有无数个附加组。
上面我们添加 mnl 到 project_rw,project_rw 就是 mnl 的附加组。
6. 额外高阶技巧:批量添加或删除
- 删除组内某成员 :
sudo gpasswd -d 用户名 组名 - 删除整个组 (需确保组内无用户正在使用):
sudo groupdel 组名
补充: 村长办公室的"三大绝密档案"
Linux 是"一切皆文件"的系统,所有的用户和组信息,其实就是写在三个纯文本文件里的。搞懂这三个文件,你就看透了 Linux 用户的本质。
1. 户籍花名册:/etc/passwd
这个文件记录了全村所有人的公开信息。所有用户都能看,但只有 root 能改。
随便挑出小李的一行,格式如下:
xiaoli:x:1000:1000::/home/xiaoli:/bin/bash
它用冒号 : 切成了 7 段:
xiaoli:用户名。x:密码占位符(早年密码真写在这里,后来发现太不安全,就移走了,现在统一用x占位)。1000:UID(用户的身份证号)。1000:GID(用户主组的群编号)。- 空字段:备注/GECOS 信息(比如真实姓名;这个例子里为空,因此两个冒号之间没有内容)。
/home/xiaoli:小李的家目录(老巢)。/bin/bash:小李登录后,对接他的"媒婆"(默认的 Shell 外壳程序)。
2. 密码保险箱:/etc/shadow
这里面存放的是经过层层加密的密码密文。这个文件极其机密,只有 root 才有权限看!
如果这行显示的是 * 或 !!,说明这个用户被锁定了,或者根本不能用来登录(比如那些打工的系统用户)。
3. 帮派名册:/etc/group
记录了村里所有的群组信息。
格式比如:dev_team:x:1005:xiaoli,laowang
意思是:有一个叫 dev_team 的组,GID 是 1005,里面的附加成员有小李和老王。
补充: 村长必学的 5 大实战指令
作为运维人员,你日常对用户进行增删改查,其实就是系统在底层帮你修改上面那三个文件。
1. 添加新用户:useradd
新用户刚创建时通常处于"没有可用密码/密码被锁定"的状态,不能直接靠密码登录。
bash
创建用户,同时明确创建家目录
useradd -m xiaowang 明确要求创建家目录 /home/xiaowang。
创建用户 + 创建家目录 + 加入附加组 dev_team
useradd -m -G dev_team xiaowang
2. 设置/修改密码:passwd
1.用xshell连接远程服务器弹窗我输入的密码就是要登陆的用户的密码
2.修改密码并不是只有 root 才能使用 passwd:普通用户执行 passwd 可以修改自己的密码,通常需要先输入自己的旧密码,再输入新密码;root 则既可以用 passwd 修改自己的密码,也可以通过 passwd xiaowang 直接修改普通用户 xiaowang 的密码。
bash
修改自己的密码
passwd
root 修改别人的密码
passwd xiaowang
3. 修改已有用户属性:usermod 🌟(最高频)
bash
将小张强行拉入 docker 组(注意:-aG 是最稳妥的写法,代表 Append Group 追加,不加 a 会把他从原来的组里踢出去!)
usermod -aG docker xiaozhang
4. 删除用户:userdel
bash
删除用户,但保留他的家目录和文件(温柔的做法)
userdel xiaowang
连人带家底全部抹除!(高危,慎用)
userdel -r xiaowang
5. 查看我是谁:id
排查权限报错时最有用的命令。敲下 id 或者 id xiaoli,系统会把你当前拥有的 UID、主组 GID 以及所有的附加组全部列出来,一目了然。
补充:文件能被执行的前提
在 Linux 世界里,判断一个文件"能不能跑起来(执行)",其实是由两个独立的检查点组成的。只有两个门票都拿到,进程才能真正跑起来。
第一门票:物理属性(文件的 x 权限)
这是我在博客里反复强调的"门禁系统"。不管这个文件里面写的是 C++ 编译后的二进制代码,还是 Bash 脚本,只要它想在终端里被直接运行,它身上必须挂着 x (Execute) 权限。
- 没有
x的后果: 当你尝试用./文件名这类方式直接执行 该文件时,通常会报Permission denied;但如果它是脚本,你仍可能通过bash script.sh、python3 script.py等方式显式交给解释器运行(此时脚本本身主要需要可读权限)。 - 逻辑: 这是安保系统对这个文件赋予的 "运行资格证"。
第二门票:内容逻辑(它真的是个"可执行"的玩意吗?)
这是很多初学者容易忽略的"灵魂拷问"。就算你给了文件 777 的满配权限,如果里面的内容根本不是"可执行"的格式,系统依然会报错。
当你把一个文件作为程序直接执行时,内核需要判断它是否属于可执行格式。常见情况包括 ELF 二进制文件的魔数,以及脚本首行的 Shebang:
-
二进制程序(ELF 格式):
比如你用g++ main.cpp -o app编译出来的app文件。这种文件包含 CPU 直接能读懂的机器码。系统一眼就能认出这是个程序,只要有x权限,直接丢给 CPU 跑。 -
脚本程序(Shell/Python/Perl):
比如script.sh。这种文件本质上是文本,CPU 不能直接把它当机器码执行。为了让内核在你使用./script.sh这类方式直接执行时可靠地知道应该启动哪个解释器,通常会在文件的第一行 写上解释器路径(Shebang):bash#!/bin/bash # 或者 #!/usr/bin/python3- 逻辑: 对"直接执行脚本"(如
./script.sh)而言,Shebang 用来告诉内核应启动哪个解释器。缺少有效 Shebang 时,直接执行可能得到Exec format error,某些 Shell 也可能在收到该错误后自行尝试按脚本解释。另一方面,如果你明确执行bash script.sh或python3 script.py,脚本本身并不要求具有x权限,也不依赖 Shebang 来选择解释器。
- 逻辑: 对"直接执行脚本"(如
💡 核心流程:两道关卡缺一不可
当你在终端敲下 ./hello 时,Linux 的运行流程是这样的:
- 安保关(权限检查):
- "我要执行这个文件,我有
x权限吗?" - (如果不满足,权限系统拦截,Permission denied。)
- "我要执行这个文件,我有
- 内核关(格式检查):
- "这个文件是二进制格式吗?或者它有正确的 Shebang 头吗?"
- (如果不满足,内核报错,Exec format error。)
- 运行关:
- "好,权限齐了,格式对头,把它丢给 CPU/解释器,开跑!"
一个经典的"翻车"场景
你写了一个 Python 脚本,明明 chmod +x 了,执行时却报错。
- 原因分析:
- 权限给了(第一门票已取)。
- 但你没写
#!/usr/bin/python3(第二门票失效)。
- 你的修复逻辑:
- 只要给文件加上第一行解释器路径,系统就立刻认出了它的"执行格式",结合你之前加上的
x权限,脚本瞬间就能跑起来了。
- 只要给文件加上第一行解释器路径,系统就立刻认出了它的"执行格式",结合你之前加上的
总结:
x 权限是门禁卡,而文件格式(二进制或 Shebang)是文件的通行证。 只有当你手里拿着"门禁卡",且文件能向内核证明"我真的是个能跑的程序"时,这行命令才会被真正执行。
补充:file 指令
file 指令是 Linux 和 Unix-like 系统中非常经典且强大的命令行工具。它的核心使命只有一个:精准识别文件的真实类型。
在 Windows 系统中,我们通常习惯通过文件扩展名(如 .exe, .jpg, .txt)来判断文件类型;但在 Linux 中,内核和 file 这类工具并不会仅凭文件后缀决定文件的真实类型 ,扩展名更多是一种命名习惯和给应用程序看的提示。一个名为 image.jpg 的文件,其真实内容完全可能不是 JPEG。file 指令就是用来识别这些文件"真实面目"的工具。
以下是对 file 指令的详细讲解:
1. file 指令的工作原理
当你对一个文件运行 file 命令时,它并不是瞎猜的,而是按照以下三个层级的顺序进行严格测试:
- 文件系统测试 (Filesystem Tests): 首先检查该文件在文件系统中的属性。判断它是普通文件、目录、符号链接(软链接)、设备文件(如字符设备、块设备)还是套接字(Socket)。
- 魔数测试 (Magic Tests): 如果是普通文件,
file会读取文件开头的几个字节。许多特定的文件格式(如 PDF, PNG, ELF 可执行文件)在文件头部都有固定的特征字节(被称为 Magic Number / 魔数 )。file会将这些字节与系统自带的魔数数据库(通常位于/usr/share/misc/magic)进行比对。这是它最核心的识别机制。 - 语言测试 (Language Tests): 如果魔数测试没有匹配到结果,且文件看起来像文本,
file会扫描文件内容,尝试判断它的字符编码(如 ASCII, UTF-8)以及是否属于某种特定的编程语言(如 C, Python, Shell 脚本,甚至 HTML 或 JSON)。
2. 基本用法与实战案例
最基础的语法是:
bash
file [选项] 文件或目录...
最简单的用法就是直接跟上文件名:
bash
file filename
示例输出分析:
-
文本文件:
bash$ file readme.txt readme.txt: UTF-8 Unicode text -
图片文件(即使你去掉了 .png 扩展名):
bash$ file my_photo my_photo: PNG image data, 1920 x 1080, 8-bit/color RGBA, non-interlaced -
Linux 可执行文件:
bash$ file /bin/ls /bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked... -
目录:
bash$ file /etc /etc: directory
3. 常用高阶参数选项
为了应对不同的使用场景,file 提供了丰富的参数。以下是日常工作中最常用的几个:
| 参数 | 功能描述 | 典型使用场景 |
|---|---|---|
-b |
简洁模式:只输出文件类型,不输出文件名。 | 写 Shell 脚本时,常用于提取类型信息而不希望混入文件名。 |
-i |
MIME 类型 :输出标准的 MIME 类型字符串(如 text/plain 或 image/jpeg),而不是人类可读的详细描述。 |
在 Web 开发或自动化处理时,需要标准的格式标记。 |
-L |
追踪链接 :如果目标是符号链接,不显示"软链接",而是直接去识别它指向的原始文件的类型。 | 检查快捷方式背后的真实文件属性。 |
-z |
尝试解读压缩内容:对支持的压缩格式继续分析解压后的内容。 | 希望同时了解压缩文件内部内容的类型。 |
-c |
检查魔数数据库 :输出解析后的 magic 数据库检查信息,常用于排错或分析 file 的识别规则。 |
调试/检查 magic 文件。 |
-f |
批量读取:从指定的文本文件中读取目标文件列表,并逐一检查。 | 配合 find 命令做大规模文件类型排查。 |
参数组合示例:
-
只获取 MIME 类型(不带文件名):
bash$ file -b -i index.html text/html; charset=utf-8 -
查看软链接的真实面目:
bash# 不加 -L 会显示它是软链接 $ file /etc/localtime /etc/localtime: symbolic link to ../usr/share/zoneinfo/Asia/Taipei # 加上 -L 会显示目标文件的类型 $ file -L /etc/localtime /etc/localtime: timezone data, version 2, 2 gmt time flags, 2 std time flags...
三)目录权限
Linux 中的权限管理是系统安全的基石。很多人在初学时,会把文件权限 和目录权限混为一谈,但这其实是两个完全不同的概念。
对于普通文件来说,读(r)、写(w)、执行(x)很好理解;但对于目录(Directory)而言,这三个字母的含义有着截然不同的"硬核"逻辑。
补充:文件的内容是详细数据,目录的内容是不是就是里面所包含的文件的属性?
严格来说,这个结论不完全准确。
在 Linux 世界里,目录的内容并不是文件属性,而是一张"映射表"。文件的真实属性存放在另一个更核心的结构中。
为了让你彻底弄透这个底层逻辑,我们需要区分 目录项(directory entry / dirent) 、内核 VFS 中的 dentry ,以及 索引节点(Inode)。
1. 目录的真正内容:只有"名字"和"身份证号"
在 Linux 中,"一切皆文件",目录确实也是一种特殊的文件。但是,如果你能用放大镜去看目录存放的"数据内容"(Data Block),你会发现里面并没有文件的权限、大小或时间等详细属性。
目录在文件系统中的数据内容,本质上保存的是一组目录项(directory entry / dirent),核心作用就是把"文件名"映射到对应的 Inode 号。教学上可以简化理解为主要包含:
- 文件名 (例如:
config.txt) - Inode 号码 (例如:
851234,这就像是文件在系统里的"身份证号")
2. 文件的属性存放在哪里?------ Inode (索引节点)
我们所说的"文件的属性"(包括读写执行权限 rwx、属主、属组、文件大小、各种时间戳,以及数据块位置等元数据)主要记录在 Inode(索引节点) 中;不同文件系统实际保存的字段会有所差异。文件名本身通常不存放在 Inode 里。
当你在目录中执行 ls -l 命令查看文件详细属性时,系统在后台实际上做了以下几步操作:
- 读取目录的内容 ,找到你输入的文件名,并提取出对应的 Inode 号码。
- 系统拿着这个 Inode 号码,去硬盘的 Inode 表 (Inode Table) 中查找到对应的 Inode 结构。
- 从这个 Inode 结构中,读取出文件的权限、大小、所有者等属性信息,并展示在屏幕上。
3. 生动的类比:电话簿与警察局档案
为了更形象地理解,我们可以打个比方:
- 目录(Directory) = 电话簿。电话簿里只写了"张三"(文件名)和"他的身份证号:123456"(Inode 号)。电话簿本身不记录张三的身高、体重或家庭住址。
- Inode = 警察局的身份档案库。你必须拿着"123456"这个身份证号去警察局查档案,才能看到张三的具体信息(文件权限、大小等)以及他家房子具体在哪条街几号(硬盘上真实数据的存储位置)。
- 文件内容(Data Block) = 张三住的房子。里面存放着真正的业务数据。
4. 为什么 Linux 要进行这样"繁琐"的分离设计?
你可能会问:把属性直接塞进目录里不是更直接吗?为什么要分离开来?
这种"文件名"与"文件实体(Inode+数据)"分离的设计,带来了 Linux 中一个极其强大的特性:硬链接 (Hard Link)。
既然目录只负责记录"名字到 Inode 号的映射",那么我们完全可以在同一个目录(或不同目录)下,创建多个不同的文件名,让它们指向同一个 Inode 号码!
bash
# 假设我们在底层操作:
文件名 A (readme.txt) ----> Inode 851234
文件名 B (备份.txt) ----> Inode 851234
这两个文件在系统中看起来是独立的两个文件,但它们底层共享同一套权限、同一套数据块。修改其中一个,另一个会同步改变,因为它们本质上就是同一个 Inode。
这也解释了为什么在 Linux 中删除一个文件,很多时候只是"闪删":
当你执行 rm 命令时,系统只是在目录中删除了"文件名与 Inode 号"的这条记录(撕掉了电话簿上的一页)。只要还有其他硬链接指向这个 Inode,或者有进程正在使用它,文件的真实属性和数据块就依然完好无损地保留在硬盘上,直到所有指向该 Inode 的链接都被清除,系统才会真正回收这块空间。
硬链接 (Hard Link)
是文件的一个别名。它和原文件指向同一个 inode(即磁盘上同一份数据),一个文件可以有多个硬链接,大家地位完全平等,没有"原文件"和"副本"之分。
软链接 (Symbolic Link / Soft Link)
是一个特殊的小文件,里面保存着另一个文件的路径(像快捷方式)。访问软链接时,系统会自动跳转到它指向的路径。
bash
创建硬链接
ln 原文件 硬链接名
创建软链接
ln -s 原文件 软链接名
1. 目录权限的本质:r、w、x 到底代表什么?
在目录的世界里,权限控制的是对目录内文件的操作权 ,而不是对目录本身内容(虽然目录本质上是个记录文件列表的特殊文件)的直接操作。
-
r(Read / 读权限 = 4)- 含义: 允许读取目录树(列表)。
- 大白话: 你可以使用
ls命令查看这个目录下有哪些文件和子目录。 - 注意: 如果只有
r没有x,你只能看到文件名,无法查看文件属性(如大小、时间),也不能进入该目录或读取里面的文件。
-
w(Write / 写权限 = 2)- 含义: 允许修改目录的内容(即目录内的文件列表)。
- 大白话: 你可以在这个目录下创建、删除、重命名或移动文件。
- ⚠️ 致命陷阱: 在普通的传统权限场景下,只要你对父目录有
w和x权限,就通常可以删除或重命名其中的目录项,即使目标文件本身对你是只读的。决定能否删除文件的关键主要是父目录权限; 不过 Sticky Bit、ACL、安全模块等机制还可能进一步限制删除行为。

-
x(Execute / 执行权限 = 1)- 含义: 允许进入(穿透)目录 。这是目录权限中最核心、最基础的权限。
- 大白话: 你可以使用
cd命令进入该目录。 - 注意: 如果没有
x权限,你的操作会被直接"挡在门外"。即使你有r权限,系统也会拒绝你访问目录内的任何具体文件。通常,目录的r和x总是成对出现的。
2. 用户身份的三个维度(U、G、O)
Linux 将权限分配给三种不同的身份,用以实现精细化管理:
u(User / 属主): 目录的拥有者。g(Group / 属组): 目录所属的用户组。组内的所有用户共享这部分权限。o(Others / 其他人): 既不是属主,也不属于该组的所有其他系统用户。
(另外还有一个 a 代表 All,即所有人,相当于 u+g+o)
3. 进入目录需要什么权限
"x"权限
在 Linux 的权限体系中,对于目录而言,x(执行)权限就是绝对的"守门员"和"通行证" 。没有 x 权限作为基础,r(读)和 w(写)权限要不然是大打折扣,要不然就是形同虚设。
1) 核心结论:穿透力决定一切
在目录的语境下,x 权限应该被理解为 "穿透权 (Search/Traverse)" 。
系统内核在处理任何涉及到该目录下文件的操作(无论是查看属性、读取内容、创建还是删除)时,第一步都会检查你是否具备穿透该目录的权限 。如果这扇大门(x 权限)被锁死,后续的所有操作都会被系统内核直接拦截,报出 Permission denied(权限拒绝)。
2) 极端场景推演(彻底弄懂 r、w、x 的相互依存)
我们假设有一个目录叫 test_dir,里面有一个文件叫 demo.txt。我们来看看在缺失 x 权限时,会发生什么诡异的现象:
场景一:只有 r,没有 x(权限:400,即 r--)------ "隔着毛玻璃看画"
- 现象描述:你可以列出目录里的文件名,但无法获取任何实质信息,也无法访问文件。
- 具体指令表现 :
- 执行
ls test_dir:可以 成功显示出demo.txt这个名字。(因为r权限允许你读取目录的 Dentry 列表,也就是上一节提到的"电话簿")。 - 执行
ls -l test_dir:报错且显示残缺信息 。系统会列出文件名,但文件的权限、属主、大小、时间等全部显示为问号?。 - 执行
cd test_dir:失败,提示权限拒绝。 - 执行
cat test_dir/demo.txt:失败 ,哪怕demo.txt自身的权限是 777 允许所有人读取,你也打不开它。
- 执行
- 底层逻辑 :你拿到了电话簿(有了
r),看到了名字,但是警察局的大门(x)对你关闭了,你无法根据名字去查阅底层 Inode 里的详细档案。
场景二:只有 w,没有 x(权限:200,即 -w-)------ "废纸一张的修改权"

- 现象描述 :这是一种完全无效的状态。理论上你拥有修改目录内容的权力,但在实际操作中寸步难行。
- 具体指令表现 :
- 执行
touch test_dir/new.txt:失败,提示权限拒绝。 - 执行
rm test_dir/demo.txt:失败,提示权限拒绝。
- 执行
- 底层逻辑 :你虽然有向"电话簿"里添加或划掉记录的权力(有了
w),但是你进不了存放这本电话簿的房间(没有x),所以你实际上什么都改不了。
系统内核要求:在修改目录内容之前,必须先成功"进入"该目录。
场景三:作为对比,如果只有 x,没有 r 和 w(权限:100,即 --x)------ "盲盒模式 / 投递箱"
- 现象描述 :这是一个非常经典的高级安全用法。你无法使用
ls查看目录里有什么(没有r),也无法创建新文件(没有w),但是,如果你事先准确知道里面某个文件的绝对路径和名字,你可以直接访问它! - 具体指令表现 :
- 执行
ls test_dir:失败,什么都看不见。 - 执行
cd test_dir:成功进入! - 执行
cat test_dir/demo.txt:成功读取!(前提是你知道有这个文件,且文件本身对你有读权限)。
- 执行
- 应用场景 :这通常用于构建安全的 Web 服务目录或私密共享通道。别人无法通过
ls窥探你的目录结构,但只要你能给出准确的 URL 或路径,就可以精准访问指定资源。
3.)最佳实践总结
基于以上底层逻辑,在日常的 Linux 系统管理和架构设计中,必须牢记以下准则:
rx常见组合 :如果你希望用户既能列出目录中的名字,又能正常访问这些目录项,通常同时赋予r和x(r-x,数字 5)。只有r没有x时,虽然可能列出文件名,但无法正常访问目录中的具体文件。wx常见组合 :如果你希望用户能在目录中创建、删除或重命名目录项,通常至少需要w和x;实际使用中往往再加r形成rwx(数字 7)。只有w没有x时,目录修改能力基本无法正常发挥。
所以,回到你的问题:是的,对于目录而言,x 权限是激活 r 和 w 实际使用价值的核心前提。
4.Linux的权限掩码
在前两轮中,我们深入剖析了文件和目录权限的底层逻辑。现在,当你真正在 Linux 系统中执行 touch 创建一个新文件,或者执行 mkdir 创建一个新目录时,系统是如何决定它们的初始权限的呢?
这就引出了 Linux 权限体系中另一个极为核心的概念:权限掩码(umask)。
1)什么是权限掩码 (umask)?
"掩码"这个词在计算机科学中很常见(比如子网掩码)。在 Linux 文件系统中,umask 就是一个"权限过滤器"或"减法器"。
对于常见的创建接口,可以把"请求的初始权限上限"这样理解:普通数据文件通常以不包含执行位的 0666 为基础,而目录通常以 0777 为基础,然后再由 umask 屏蔽掉相应权限位:
- 新建目录的默认最大权限:
0777(rwxrwxrwx,因为没有执行权限x就无法进入目录,所以目录必须默认有x)。(以数字 0 开头的整数,代表它是一个八进制数。) - 新建文件的默认最大权限:
0666(rw-rw-rw-,去掉了所有的执行权限x)。
创建可执行程序的工具可以请求包含
x的权限位,因此最终常见为0755等权限;它仍然会受到当前umask的影响。普通touch创建的数据文件则通常从0666这一上限出发。
但是,如果你每次新建目录都是 777,新建文件都是 666,这显然极不安全。umask 的作用就是在这个"最大权限"的基础上,"遮盖"或"剥夺"掉一部分权限,从而得出最终的实际权限。
2) 底层计算逻辑:绝不是简单的减法,而是位运算
很多基础教程会简单地告诉你:最终权限 = 默认最大权限 - umask。
在大多数常见情况(如 umask 为 022)下,这个减法看似是成立的(777 - 022 = 755)。
但这是一个严重的误区! 作为一个计算机科学专业的开发者,你必须知道它的底层真相是位运算:
公式: 最终权限 = 默认最大权限 & (~umask)
即:默认权限 与上 umask的反码。
我们用一个极端的例子来证伪"减法论":
假设当前的 umask 被设置为了 033。
如果是简单的数字相减:新建文件的权限将是 666 - 033 = 633。这意味着文件有了执行权限(3代表 -wx),这完全违背了 Linux 的安全设计!
真实的底层位运算过程如下(以创建文件,umask=033 为例):
- 文件默认最大权限 (0666):
二进制表示:110 110 110(rw- rw- rw-) - umask 值 (0033):
二进制表示:000 011 011(--- -wx -wx) - 对 umask 取反 (~umask):
二进制表示:111 100 100(rwx r-- r--) -
执行按位与运算 (&):
110 110 110(默认最大权限 666)
111 100 100(取反后的 umask)110 100 100(按位与的结果) - 最终结果转换回八进制:
110= 6 (rw-)
100= 4 (r--)
100= 4 (r--)
最终文件权限为0644(rw-r--r--),而不是633!
通俗理解:
umask中哪一位是1,就硬性地将默认权限中对应的哪一位"抠掉"变成0。如果默认权限中那一位本来就是0(比如文件默认没有x),你再怎么抠它,它还是0。
3) 系统默认的 umask 设置
很多教学环境和发行版配置中,普通用户和 root 可能采用不同的默认 umask;一个常见的教学示例是:
- 普通用户默认 umask:
0002- 新建目录权限:
777 & (~002) = 775(drwxrwxr-x) - 新建文件权限:
666 & (~002) = 664(-rw-rw-r--) - 逻辑:允许同组用户进行读写协作。
- 新建目录权限:
- root 用户默认 umask:
0022- 新建目录权限:
777 & (~022) = 755(drwxr-xr-x) - 新建文件权限:
666 & (~022) = 644(-rw-r--r--) - 逻辑:按这个示例,组用户和其他用户的写权限会被屏蔽。
- 新建目录权限:
实际默认
umask由发行版、登录方式和系统配置决定,因此不要把0002/0022当成所有 Linux 系统都固定不变的值。
4)如何查看与修改 umask
查看当前 umask:
bash
直接输出八进制数字
$ umask
0022
输出易读的符号形式(显示的是最终保留的权限,而不是要去掉的权限)
$ umask -S
u=rwx,g=rx,o=rx
临时修改(仅当前终端会话有效):
bash
将当前终端的掩码设置为 0027(属主全权,同组只读,其他人无任何权限)
$ umask 0027
umask 0027是临时修改
你在终端中直接敲下 umask 0022 这样的指令时,实际上只是修改了当前这个终端窗口(当前 Shell 进程)的 临时 运行环境。当你关闭这个终端时,该进程的内存会被系统回收,你所做的修改也就随之灰飞烟灭了。当你再次打开一个新的终端时,系统会启动一个新的 Shell 进程。这个新进程会去读取系统的"配置文件",以此来决定初始的 umask 是多少。
永久修改:
你需要将 umask 指令写入 Shell 的环境配置文件中。
- 全局生效(影响所有用户):编辑
/etc/profile。 - 仅当前用户生效:编辑用户家目录下的
~/.bashrc或~/.profile,在文件末尾添加一行umask 0027,然后执行source ~/.bashrc使其生效。
5 目录的高阶权限:Sticky Bit (粘滞位 / 保护位)
在前几篇教程中,我们从基础的目录穿透权限(执行权),一路深入到了八进制权限掩码。现在,我们将补齐 Linux 基础安全体系中最特殊的一块拼图:粘滞位(Sticky Bit) 。解决多用户之间共享文件的问题
1) 痛点场景重现:共享目录的"黑暗森林"法则
在 Linux 系统中,有一个所有用户都非常熟悉的目录:/tmp(临时目录)。
由于任何用户运行的程序都可能需要产生临时数据,所以系统必须允许所有人在 /tmp 下创建和写入文件。这就要求 /tmp 的基础权限必须是最高级别的 777(可读、可写、可进入)。
我们在前面探讨目录权限时强调过一个致命逻辑:只要我对一个目录有"写"权限和"进入"权限,我就可以删除里面的任何文件,无论这个文件是谁建的!
如果不加干预,/tmp 目录就会变成一个混乱的"黑暗森林":
- 用户 A 正在编译一个大型项目,在
/tmp里存了大量的中间文件。 - 用户 B 登录系统,执行了一句
rm -rf /tmp/*。 - 结果:用户 A 的心血瞬间灰飞烟灭,即使 A 的文件对 B 是设置了"只读"的。
为了解决这种"拥有目录写权限就能肆意妄为"的设计缺陷,Linux 引入了粘滞位。
2)粘滞位的核心机制:权限的"精准收缩"
当一个目录被赋予了粘滞位之后,它的"写"权限逻辑会发生非常微妙但极其关键的变化。
核心规则:
在一个带有粘滞位的目录中,即便你对该目录拥有满格的 777 权限(可以任意创建文件),但当你试图删除或重命名该目录下的某个文件时,系统内核会进行严格的身份校验。
在用户本身已经具备对该目录进行删除/重命名所需基础权限的前提下,Sticky Bit 会进一步要求删除者满足以下条件之一:
- 你是该文件的属主(拥有者)。
- 你是该目录的属主。
- 你是拥有至高无版权限的 root 用户。
大白话总结:在带有粘滞位的共享房间里,每个人都可以往里面放自己的私人物品,也可以看别人的物品(如果别人允许),但是,你绝对不能扔掉或改名别人的私人物品。
3) 表现形式:底层细节里的 t 与 T
Sticky Bit (粘滞位 / 保护位)的表现形式: drwxrwxrwt(最后的 t 就是 Sticky Bit), 数字表示: 在原来的三位数字前加个 1,即 1777。
当你使用 ls -ld 查看目录详细信息时,粘滞位会占据 其他人(Others) 权限位的最后一个字符(即原本执行权限 x 的位置)。
粘滞位是一个独立的高级权限。但在屏幕显示时,Linux 选择将它"叠加"并展示在 others 的 x 权限位上。 它改变的不是一个简单的字母,而是彻底改写了该目录下的"文件删除许可规则"。也就是说粘滞位和o的x其实没有任何关系,只是呈现的时候被放在这个位置上而已
这里有一个非常考验专业基本功的细节------大小写之分:
- 带有小写
t: 例如drwxrwxrwt- 含义: 这个目录既有基础的执行权限(
x),又被设置了粘滞位 。这是最正常、最正确的使用状态(比如/tmp目录)。
- 含义: 这个目录既有基础的执行权限(
- 带有大写
T: 例如drwxrwxrwT- 含义: 这个目录被设置了粘滞位,但它本身没有执行权限(
x)。 - 说明: 大写
T只表示"Sticky Bit 已设置,但 Others 的x位没有设置"。Sticky Bit 本身仍然存在,并不能简单说它"无效";只是按 Others 身份访问的用户缺少目录穿透权限,通常无法正常进入该目录。
- 含义: 这个目录被设置了粘滞位,但它本身没有执行权限(
在 Linux 的权限字符串(如 drwxrwxrwt)中,最后一位(第 11 个字符)原本是 other 的执行权限位:
如果 other 有执行权限(x),且设置了粘滞位,则显示为小写 t。
如果 other 没有执行权限(-),但设置了粘滞位,则显示为大写 T。
4) 实操指令演示
配置粘滞位非常简单,同样支持符号法和数字(八进制)法:
方法一:符号法 (直观易懂)
bash
# 给共享目录添加粘滞位
chmod +t /data/share_folder
# 移除粘滞位
chmod -t /data/share_folder
方法二:数字法 (底层硬核)
回顾上一篇关于 0777 的知识,四位数字的第一位代表特殊权限。粘滞位对应的数值是 1。
bash
# 赋予最高基础权限,并开启粘滞位
chmod 1777 /data/share_folder
补充: chmod +x 到底代表什么?
1. 平时用起来,记住这一句就够了
在日常工作中,chmod +x 基本等于"让所有人都能执行这个文件"。
你敲 chmod +x script.sh,系统默认会给文件主人、同组用户、其他所有人 都加上执行权限。效果和 chmod a+x 几乎一样。
所以如果你只是想让自己或大家能运行一个脚本,直接写
+x完全没问题,不用纠结。
2. 为什么官方文档说它"不等于" a+x?(技术细节)
严格的技术规范里,省略 ugoa 时,系统会多看一眼安全掩码(umask)。
但关键来了:
默认的 umask(比如 022)只屏蔽"写权限(w)",从来不屏蔽"执行权限(x)"。
所以:
- 你执行
chmod +x→ 加的是x(执行权限)→umask不管x→ 顺利通过,给所有人加上。 - 你执行
chmod +w→ 加的是w(写权限)→umask屏蔽了组和其他人的w→ 结果只给文件主人加了写权限。
结论 :
"单独写 + 会先看 umask:如果 umask 屏蔽了某个身份的该权限,那么这次操作就自动跳过这个身份;除非明确指明 ugoa,才能强制执行,无视 umask。"
3. 什么时候 chmod +x 真的会"失灵"?(极少数情况)
除非你自己手动把 umask 改成了屏蔽执行权限,比如改成 umask 111(禁止所有用户新建有执行权限的文件)。
这时候你再敲 chmod +x file:
- 系统一看:"umask 不让我动
x权限位" → 命令虽然不报错,但实际上什么都没加上。 - 此时只有敲
chmod a+x file才能强制加上执行权限。
一句话终极总结(背下来就行)
日常开发中,
chmod +x就放心当"给所有人加执行权限"用。只有在你折腾
umask环境变量,或者要给组/其他人精确控制读写权限时,才需要刻意区分+和a+。写脚本为了严谨,直接写chmod a+x永远不出错。
补充: 两个普通用户如何进入到对方的家目录下
这个问题刚好能将我们之前讲过的 "目录穿透权(x 权限)" 完美运用到实战中。
在现代 Linux 系统(如 CentOS 7/8 或 Ubuntu)中,为了保护用户隐私,默认创建的用户家目录权限通常被设置得非常严格。
比如 userA 的家目录 /home/userA,权限往往是 700 (drwx------) 或者 750 (drwxr-x---)。
这意味着,外人(Others)连最基础的 x 权限都没有,更别提进门了。如果两个普通用户(假设是 userA 和 userB)想要互相"串门",也就是互相 cd 进入对方的家目录,我们需要为对方 "配钥匙"。
这里有三种技术方案,按专业程度从低到高,我为你详细拆解:
方案一:简单粗暴的"大门敞开"模式 (修改 Others 权限)
这是初学者最容易想到的方法,直接利用我们学过的 chmod 命令,给家目录的"其他人(Others)"加上读和进入的权限。
实操步骤:
-
userA登录系统 ,开放自己的家目录:bashchmod o+rx /home/userA -
userB登录系统 ,开放自己的家目录:bashchmod o+rx /home/userB
底层逻辑与致命缺陷:
- 逻辑: 你们各自给自己的家目录增加了
r(看门牌号)和x(穿透进入)的权限。 - 缺陷: 这种做法是极其不安全的!因为
o代表系统里的所有人 。这就好比为了让朋友来你家,你直接把自家大门给拆了。不仅userB能进,系统里的userC、userD,甚至未来某个被黑客攻破的弱密码账号,全都能大摇大摆地进入你的家目录翻找文件。(强烈不推荐在公司生产环境使用)
方案二:传统的"发群名片"模式 (用户组协作)
这是 Linux 早期为了解决协同工作而设计的标准方案。既然不能向所有人(Others)开放,那我们就建立一个小圈子(Group),只向圈子里的人开放。
实操步骤(需 root 管理员介入):
-
管理员出面,创建一个名为
dev_team的共享用户组:bashsudo groupadd dev_team -
把
userA和userB都拉进这个群里:bashsudo usermod -aG dev_team userA sudo usermod -aG dev_team userB -
userA和userB分别将自己家目录的属组(Group)改成这个共享组,并给属组开放rx权限:bash# userA 执行 chgrp dev_team /home/userA chmod g+rx /home/userA # userB 执行 chgrp dev_team /home/userB chmod g+rx /home/userB
底层逻辑与局限性:
- 逻辑: 利用 UGO 模型中的
G(属组)来实现权限共享。 - 局限性: 虽然比方案一安全,但把整个家目录的属组改掉,是一件比较"重"的操作。如果以后还要加
userC进来,但只允许userC访问userA不允许访问userB,这种传统的群组模型就显得捉襟见肘,很难进行极其精细的控制。
方案三:高级玩家的"精准发通行证"模式 (ACL 访问控制列表)
这是现代 Linux 运维中最标准、最优雅、最专业的解决方案!
ACL(Access Control List)的存在,就是为了打破传统的 U、G、O 三权分立的结界。它可以实现:在不改变原有的属主、属组,且绝对不向 Others 开放的前提下,精准地向某一个特定的人发放权限。
语法规则:
bash
setfacl -m 规则实体:用户名:权限 目标文件或目录
拆解成 4 个部分:
| 部分 | 含义 | 可选值 |
|---|---|---|
setfacl |
命令本身 | 固定 |
-m |
Modify(修改/添加) | -m(添加/修改)、-x(删除单个)、-b(删除全部) |
| 规则实体 | 给谁设置 | u(用户)、g(组)、m(有效权限掩码)、d(默认继承) |
: |
分隔符 | 固定冒号 |
| 用户名/组名 | 具体的账号 | 必须是系统中存在的用户或组 |
: |
分隔符 | 固定冒号 |
| 权限 | 授予什么权限 | r(读)、w(写)、x(执行/穿透)、rw、rx、rwx、-(无权限) |
实操步骤(假设文件系统支持 ACL,且用户是自己家目录的属主;这种情况下通常无需 root):
-
userA操作:精准给userB颁发通行证bash-m 代表 modify(修改), u:userB:rx 代表授予用户 userB 读取和穿透权限 setfacl -m u:userB:rx /home/userA -
userB操作:精准给userA颁发通行证bashsetfacl -m u:userA:rx /home/userB
如何验证这个"隐形的通行证"?
此时如果你在 /home 目录下敲 ls -l,你会发现一个极其微妙的变化:
drwxr-x---+ userA userA 4096 /home/userA
注意到权限字符串最后的那个 + 号 了吗?
这个加号就是在宣告:"这个目录除了传统的 UGO 权限外,还挂载了高级的 ACL 精细权限表!"
你可以使用 getfacl 命令来查看这张隐藏的权限表:
bash
$ getfacl /home/userA
# file: home/userA
# owner: userA
# group: userA
user::rwx
user:userB:r-x <-- 这里清晰地记录着:系统单独给 userB 开了特权!
group::---
mask::r-x
other::---
传统的 chmod (UGO模型) 就像是门锁的基础开关,而 setfacl (ACL模型) 则是现代智能门锁的"临时指纹授权"。