2.Linux基础指令下【由浅入深-Linux】

文章目录

    • 第四章: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 的最大痛点:密码危机)
        • [第二招:尚方宝剑 ------ `sudo` (Superuser DO)](#第二招:尚方宝剑 —— sudo (Superuser DO))
          • [1. 它是如何运作的?(白名单机制)](#1. 它是如何运作的?(白名单机制))
          • [2. 实战用法](#2. 实战用法)
          • [2.1 `sudo -u`:指定以谁的身份执行](#2.1 sudo -u:指定以谁的身份执行)
          • [3. 为什么企业里全都在用 `sudo`?](#3. 为什么企业里全都在用 sudo?)
        • 总结:后端开发的黄金生存法则
      • 补充:终端的"俄罗斯套娃"
        • [1. 终端的"俄罗斯套娃"](#1. 终端的“俄罗斯套娃”)
        • [2. 如果再敲一次 `exit` 会怎样?](#2. 如果再敲一次 exit 会怎样?)
      • [补充:怎么在 /etc/sudoers里面添加用户?](#补充:怎么在 /etc/sudoers里面添加用户?)
      • [2) 动态变脸:UGO 身份匹配游戏 (Role)](#2) 动态变脸:UGO 身份匹配游戏 (Role))
        • [第一问:你是这房子的主人吗?(User - `u`)](#第一问:你是这房子的主人吗?(User - u))
        • [第二问:你是主人家属/团队的吗?(Group - `g`)](#第二问:你是主人家属/团队的吗?(Group - g))
        • [第三问:原来你是个路人!(Other - `o`)](#第三问:原来你是个路人!(Other - o))
      • 3)公式右半边:文件属性(这栋房子挂着什么锁?)
        • [锁的三个孔位(`rwx` 到底能干嘛?)](#锁的三个孔位(rwx 到底能干嘛?))
        • [深入剖析 Group(家人/团队):主组与附加组](#深入剖析 Group(家人/团队):主组与附加组)
      • 补充:完整流程
        • [一、 关于"三把锁"(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. 八进制数字表示法(最快的心算法))
        • [二、 如何修改权限:`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 参数)
          • [💡 终极排障口诀](#💡 终极排障口诀)
      • [补充章节: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)
      • [补充: 村长必学的 5 大实战指令](#补充: 村长必学的 5 大实战指令)
        • [1. 添加新用户:`useradd`](#1. 添加新用户:useradd)
        • [2. 设置/修改密码:`passwd`](#2. 设置/修改密码:passwd)
        • [3. 修改已有用户属性:`usermod` 🌟(最高频)](#3. 修改已有用户属性:usermod 🌟(最高频))
        • [4. 删除用户:`userdel`](#4. 删除用户:userdel)
        • [5. 查看我是谁:`id`](#5. 查看我是谁:id)
      • 补充:文件能被执行的前提
      • [补充:`file` 指令](#补充:file 指令)
        • [1. `file` 指令的工作原理](#1. file 指令的工作原理)
        • [2. 基本用法与实战案例](#2. 基本用法与实战案例)
        • [3. 常用高阶参数选项](#3. 常用高阶参数选项)
    • 三)目录权限
      • 补充:文件的内容是详细数据,目录的内容是不是就是里面所包含的文件的属性?
        • [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,没有 rw(权限:100,即 --x)—— “盲盒模式 / 投递箱”)
        • 3.)最佳实践总结
      • 4.Linux的权限掩码
        • [1)什么是权限掩码 (umask)?](#1)什么是权限掩码 (umask)?)
        • [2) 底层计算逻辑:绝不是简单的减法,而是位运算](#2) 底层计算逻辑:绝不是简单的减法,而是位运算)
        • [3) 系统默认的 umask 设置](#3) 系统默认的 umask 设置)
        • [4)如何查看与修改 umask](#4)如何查看与修改 umask)
      • [5 目录的高阶权限:Sticky Bit (粘滞位 / 保护位)](#5 目录的高阶权限:Sticky Bit (粘滞位 / 保护位))
      • [补充: `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 中,实现阶级跃迁主要有两大绝招:susudo。它们虽然看起来像双胞胎,但背后的逻辑和应用场景却天差地别。

第一招:灵魂夺舍 ------ 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 在获得授权后直接让 commandbob 的 UID/GID 运行;但 alice → bob 这个切换行为本身仍然必须获得 sudo 授权 。如果你本来就是 bob,直接执行 command 即可,没必要 sudo -u bob

3. 为什么企业里全都在用 sudo

相比于 susudo 拥有三大碾压级优势:

  1. 更安全: 不需要向任何人泄露最高机密的 Root 密码,并且可以按命令进行授权。
  2. 精准授权(最小特权原则): 村长可以在小本本里精细规定:"小李的 sudo 只能用来重启 Nginx 服务,不能用来删除文件"。而 su 是一给就给全部权限。
  3. 可追溯: sudo 通常会按系统和 sudoers 的日志配置记录命令调用信息(常见日志位置包括 /var/log/secure/var/log/auth.log 或 systemd journal),因此比共享 Root 密码更便于审计和追踪。

注意:sudo 认证成功后通常会有一段认证缓存时间 ,在有效期内再次执行 sudo 可能不需要重新输入密码。具体时长由 sudoers 中的 timestamp_timeout 等配置决定,不同发行版和管理员配置可能不同,不能固定记成 15 分钟。

总结:后端开发的黄金生存法则

懂得了这两种转换逻辑后,在你以后的 C++ 后端开发或服务器运维生涯中,请把下面这两条原则刻在骨子里:

  1. 封印 Root 账号,拒绝直接登录:
    在正规公司的生产服务器上,第一件事就是修改 SSH 配置文件(sshd_config),禁止 Root 账号直接远程登录PermitRootLogin no)。所有人必须先用普通账号登录服务器。
  2. 能用 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 仍然在下面等待。

我们来重演一下这个过程:

  1. 初始状态: 你以普通村民 xiaoli 的身份登录了服务器。(此时你处于第一层套娃)。
  2. 变身神仙: 你敲入 su - root 并输入了村长的密码。此时,系统并没有杀掉原来的 xiaoli Shell,而是启动了一个以 root 身份运行的新 Shell。(此时你处于第二层套娃,root 状态,但仍然使用同一个终端设备/终端窗口)。
  3. 下凡降级: 你在 root 状态下敲入了 exit 或按了 Ctrl + D
    • 系统底层做了什么? 最外层的 root Shell 退出,控制权返回给下面仍在等待的 xiaoli Shell。
    • 结果: 你自然而然地露出了里面的第一层套娃,也就是变回了 xiaoli
2. 如果再敲一次 exit 会怎样?

既然你已经变回了 xiaoli(第一层套娃),如果你这个时候再敲一次 exit,会发生什么?

  • 它会让当前这个 xiaoli Shell 退出。
  • 最终结果: 如果它正是登录 Shell,那么你通常会注销当前登录会话;远程 SSH 会断开。图形终端窗口是否随之关闭,则取决于终端模拟器的设置。

场景 A: 小李 登录 ➡️ su - root 变成村长 ➡️ exit 销毁村长外壳 ➡️ 退回小李。

场景 B: root 登录 ➡️ su - 小李 变成小李 ➡️ exit 销毁小李外壳 ➡️ 退回 root。

回归"Linux 村"的比喻:

你(小李)用密码打开了村长办公室的门,走进去坐在了老板椅上(su - root)。

当你处理完事情,敲下 exit,就相当于你走出了村长办公室,并把门在身后重重地关上反锁了

这时你站在走廊里(变回小李),如果你想再进去,推门是推不开的,你只能重新掏出钥匙(再输一次密码)开门。

补充:怎么在 /etc/sudoers里面添加用户?

把一个普通村民的名字写进"白名单(sudoers)",赋予他使用尚方宝剑的权力,这是村长(root)的专属特权。

在这个过程中,有一个全网无数新手痛哭流涕的致命天坑。为了让你安全地完成提权,我们分步骤来详细讲解。

🚨 绝对警告:永远不要直接 vim /etc/sudoers

直接用 vivim 编辑 /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:常规授权(需要输小李自己的密码,推荐)

    text 复制代码
    root    ALL=(ALL)       ALL
    xiaoli  ALL=(ALL)       ALL
  • 选项 B:极致信任(执行 sudo 时连密码都不用输,高危!通常只给自动化脚本用)

    text 复制代码
    root    ALL=(ALL)       ALL
    xiaoli  ALL=(ALL)       NOPASSWD: ALL
  • 选项 C:精准限制(小李只能用 sudo 重启 Nginx,干别的都不行,极度安全)

    text 复制代码
    root    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 阅读内容: 能用 catvim 看到文件里面写了什么。 查看列表: 能用 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_teamdocker,小李就能用他附加组的身份,合法开启这把锁!

补充:完整流程

一、 关于"三把锁"(U、G、O):绝对不是同时开!而是"只开一把"

在这三把锁面前,你不需要、也不能同时打开它们。 系统的安保卫士有着极度死板的 "唯一匹配原则(一锤子买卖)"

  1. 按顺序查身份: 卫士会严格按照 User(房主) -> Group(家人) -> Other(路人) 的顺序查你的户口。
  2. 一旦命中,立刻锁定: 只要你在某一步被确认了身份,卫士就会直接把对应的那把锁扔给你,并且当场把另外两把锁砸碎(忽略)

💡 举个极端但非常经典的"坑人"例子:

假设村长建了一个文件,权限设成了这样:--- --- rwx (房主:焊死;家人:焊死;路人:满配)。

  • 如果是路人小李来: 卫士查到小李是 Other,把最后一把 rwx 的锁交给他,小李开开心心地读写执行。
  • 如果是普通用户房主本人来: 卫士查到他是 User,只检查第一组 ---。房主抗议说:"凭什么路人都能看,我是房主反而不能看?"
  • 卫士的回答是无情的: "抱歉,既然你是房主,你就只能用房主这把锁。这把锁焊死了,你就进不去。我不管路人的锁是什么样。"

结论: 三把锁之间是互斥 的,系统只认符合你身份的那唯一一把锁

二、 关于锁上的"三个孔"(r、w、x):独立开关,各取所需

当你拿到属于你的那把锁之后,锁上的 r(读)、w(写)、x(执行/进入)这三个孔,不是串联的,而是并联的"独立开关"

只要其中一个孔是开的,你就能执行它对应的单一动作。

  • 只有 r 开着 (r--): 你可以趴在窗户上看(cat 读取内容),但你想塞垃圾进去(写入)或者推门进去(执行),就会被电击(Permission denied)。
  • 只有 w 开着 (-w-): 这是一个非常奇葩但合法的权限。你可以闭着眼睛往房间里扔东西(追加内容),但你不能看里面原来有什么。
  • 只有 x 开着 (--x): 你可以按遥控器让房间里的机器跑起来(执行程序),但你不知道机器的代码是怎么写的。

⚠️ 唯一的致命关联(目录大坑再次强调):

刚才说的"独立开关"对普通文件是 100% 成立的。

但是面对"目录(房间)"时,x 孔变成了物理大门! > 只要 x 没有开,你就进不去房间。此时就算你手里的 rw 开关都是亮着的,你也只能站在院墙外面干瞪眼。

总结提炼

你可以把这套系统想象成去银行金库:

  1. 看人给锁: 银行保安先核实你是行长、员工还是客户。确认身份后,只把你带到属于你那台专属 ATM 机前(只开属于你的那把锁)。
  2. 按孔办事: 这台 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) = 4
  • w (Write) = 2
  • x (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.cppchmod g-w main.cpp(剥夺组的写权限)。
  • 同类示例还有:chmod u+w /home/abc.txtchmod o-x /home/abc.txtchmod a=x /home/abc.txt
2. 数字派:一步到位

适用于你清楚地知道最终三位身份分别要什么权限。

  • 公式: chmod [三个数字] [文件名]

实战场景:

  • 设置一个只有你自己能读写的私密文档:chmod 600 my_secret.txt
  • 设置一个标准的 C++ 编译后程序:chmod 755 a.out
  • 其他三位八进制示例:chmod 664 /home/abc.txtchmod 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 参数

在真实的后端服务器部署中,老程序员极少会分开去敲 chownchgrp,因为太麻烦了。

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,请在脑海里默念这三步排查法:

  1. 先查户口(ls -l:看看房产证和帮派是不是自己的名字。
  2. 人不对,先换人(chown :如果名字不对,立刻用 sudo chown 把归属权抢回来。
  3. 人对了,再换锁(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 用户名 组名

    bash 复制代码
    sudo gpasswd -a mnl project_rw

    这个方法不需要加 -a(它本身默认就是添加),相对更直观,不容易误操作。

3. 如何查看组里的成员
  • 查看当前用户属于哪些组 :直接用 groups 命令。

    bash 复制代码
    groups
    # 或指定查看某用户
    groups mnl
  • 查看系统所有组及成员 :读取 /etc/group 文件,或使用 getent

    bash 复制代码
    getent group project_rw

    输出格式为:组名:密码占位符:GID:成员列表(逗号分隔)

4. ⚠️ 至关重要的"生效时机"(新手极易踩坑)

你执行 usermodgpasswd 将用户加入组后,当前已经打开的终端会话(Shell)不会立刻生效

  • 如果你用 groups 命令查看,发现新组已经显示出来了(因为读取了 /etc/group),但实际权限并未生效
  • 解决方法(二选一)
    1. 退出当前 SSH 会话,重新登录(最稳妥)。
    2. 在当前终端执行 newgrp 组名 临时切换身份(仅影响当前终端,重启终端后仍需重新登录)。

只有重新登录后,新加入的组权限才会真正作用于你执行 chmod 等操作时。

5. 主要组(Primary) vs 附加组(Supplementary)------ 小科普
  • 主要组(主组):创建用户时默认生成的同名组。用户新建文件时,文件默认属于这个组。
  • 附加组(辅助组) :你用 usermod -aG 添加的组。一个用户只能有一个主组,但可以有无数个附加组。

上面我们添加 mnlproject_rwproject_rw 就是 mnl 的附加组。

6. 额外高阶技巧:批量添加或删除
  • 删除组内某成员sudo gpasswd -d 用户名 组名
  • 删除整个组 (需确保组内无用户正在使用):sudo groupdel 组名

补充: 村长办公室的"三大绝密档案"

Linux 是"一切皆文件"的系统,所有的用户和组信息,其实就是写在三个纯文本文件里的。搞懂这三个文件,你就看透了 Linux 用户的本质。

1. 户籍花名册:/etc/passwd

这个文件记录了全村所有人的公开信息。所有用户都能看,但只有 root 能改。

随便挑出小李的一行,格式如下:

xiaoli:x:1000:1000::/home/xiaoli:/bin/bash

它用冒号 : 切成了 7 段:

  1. xiaoli:用户名。
  2. x :密码占位符(早年密码真写在这里,后来发现太不安全,就移走了,现在统一用 x 占位)。
  3. 1000:UID(用户的身份证号)。
  4. 1000:GID(用户主组的群编号)。
  5. 空字段:备注/GECOS 信息(比如真实姓名;这个例子里为空,因此两个冒号之间没有内容)。
  6. /home/xiaoli:小李的家目录(老巢)。
  7. /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.shpython3 script.py 等方式显式交给解释器运行(此时脚本本身主要需要可读权限)。
  • 逻辑: 这是安保系统对这个文件赋予的 "运行资格证"
第二门票:内容逻辑(它真的是个"可执行"的玩意吗?)

这是很多初学者容易忽略的"灵魂拷问"。就算你给了文件 777 的满配权限,如果里面的内容根本不是"可执行"的格式,系统依然会报错。

当你把一个文件作为程序直接执行时,内核需要判断它是否属于可执行格式。常见情况包括 ELF 二进制文件的魔数,以及脚本首行的 Shebang:

  1. 二进制程序(ELF 格式):
    比如你用 g++ main.cpp -o app 编译出来的 app 文件。这种文件包含 CPU 直接能读懂的机器码。系统一眼就能认出这是个程序,只要有 x 权限,直接丢给 CPU 跑。

  2. 脚本程序(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.shpython3 script.py,脚本本身并不要求具有 x 权限,也不依赖 Shebang 来选择解释器。
💡 核心流程:两道关卡缺一不可

当你在终端敲下 ./hello 时,Linux 的运行流程是这样的:

  1. 安保关(权限检查):
    • "我要执行这个文件,我有 x 权限吗?"
    • (如果不满足,权限系统拦截,Permission denied。)
  2. 内核关(格式检查):
    • "这个文件是二进制格式吗?或者它有正确的 Shebang 头吗?"
    • (如果不满足,内核报错,Exec format error。)
  3. 运行关:
    • "好,权限齐了,格式对头,把它丢给 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 命令时,它并不是瞎猜的,而是按照以下三个层级的顺序进行严格测试:

  1. 文件系统测试 (Filesystem Tests): 首先检查该文件在文件系统中的属性。判断它是普通文件、目录、符号链接(软链接)、设备文件(如字符设备、块设备)还是套接字(Socket)。
  2. 魔数测试 (Magic Tests): 如果是普通文件,file 会读取文件开头的几个字节。许多特定的文件格式(如 PDF, PNG, ELF 可执行文件)在文件头部都有固定的特征字节(被称为 Magic Number / 魔数 )。file 会将这些字节与系统自带的魔数数据库(通常位于 /usr/share/misc/magic)进行比对。这是它最核心的识别机制。
  3. 语言测试 (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/plainimage/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 号。教学上可以简化理解为主要包含:

  1. 文件名 (例如:config.txt
  2. Inode 号码 (例如:851234,这就像是文件在系统里的"身份证号")
2. 文件的属性存放在哪里?------ Inode (索引节点)

我们所说的"文件的属性"(包括读写执行权限 rwx、属主、属组、文件大小、各种时间戳,以及数据块位置等元数据)主要记录在 Inode(索引节点) 中;不同文件系统实际保存的字段会有所差异。文件名本身通常不存放在 Inode 里。

当你在目录中执行 ls -l 命令查看文件详细属性时,系统在后台实际上做了以下几步操作:

  1. 读取目录的内容 ,找到你输入的文件名,并提取出对应的 Inode 号码
  2. 系统拿着这个 Inode 号码,去硬盘的 Inode 表 (Inode Table) 中查找到对应的 Inode 结构。
  3. 从这个 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)

    • 含义: 允许修改目录的内容(即目录内的文件列表)
    • 大白话: 你可以在这个目录下创建、删除、重命名或移动文件。
    • ⚠️ 致命陷阱: 在普通的传统权限场景下,只要你对父目录有 wx 权限,就通常可以删除或重命名其中的目录项,即使目标文件本身对你是只读的。决定能否删除文件的关键主要是父目录权限; 不过 Sticky Bit、ACL、安全模块等机制还可能进一步限制删除行为。
  • x (Execute / 执行权限 = 1)

    • 含义: 允许进入(穿透)目录 。这是目录权限中最核心、最基础的权限。
    • 大白话: 你可以使用 cd 命令进入该目录。
    • 注意: 如果没有 x 权限,你的操作会被直接"挡在门外"。即使你有 r 权限,系统也会拒绝你访问目录内的任何具体文件。通常,目录的 rx 总是成对出现的。

2. 用户身份的三个维度(U、G、O)

Linux 将权限分配给三种不同的身份,用以实现精细化管理:

  1. u (User / 属主): 目录的拥有者。
  2. g (Group / 属组): 目录所属的用户组。组内的所有用户共享这部分权限。
  3. 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,没有 rw(权限:100,即 --x)------ "盲盒模式 / 投递箱"
  • 现象描述 :这是一个非常经典的高级安全用法。你无法使用 ls 查看目录里有什么(没有 r),也无法创建新文件(没有 w),但是,如果你事先准确知道里面某个文件的绝对路径和名字,你可以直接访问它
  • 具体指令表现
    • 执行 ls test_dir失败,什么都看不见。
    • 执行 cd test_dir成功进入!
    • 执行 cat test_dir/demo.txt成功读取!(前提是你知道有这个文件,且文件本身对你有读权限)。
  • 应用场景 :这通常用于构建安全的 Web 服务目录或私密共享通道。别人无法通过 ls 窥探你的目录结构,但只要你能给出准确的 URL 或路径,就可以精准访问指定资源。
3.)最佳实践总结

基于以上底层逻辑,在日常的 Linux 系统管理和架构设计中,必须牢记以下准则:

  1. rx 常见组合 :如果你希望用户既能列出目录中的名字,又能正常访问这些目录项,通常同时赋予 rxr-x,数字 5)。只有 r 没有 x 时,虽然可能列出文件名,但无法正常访问目录中的具体文件。
  2. wx 常见组合 :如果你希望用户能在目录中创建、删除或重命名目录项,通常至少需要 wx;实际使用中往往再加 r 形成 rwx(数字 7)。只有 w 没有 x 时,目录修改能力基本无法正常发挥。

所以,回到你的问题:是的,对于目录而言,x 权限是激活 rw 实际使用价值的核心前提。

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 为例):

  1. 文件默认最大权限 (0666):
    二进制表示:110 110 110 (rw- rw- rw-)
  2. umask 值 (0033):
    二进制表示:000 011 011 (--- -wx -wx)
  3. 对 umask 取反 (~umask):
    二进制表示:111 100 100 (rwx r-- r--)
  4. 执行按位与运算 (&):
    110 110 110 (默认最大权限 666)
    111 100 100 (取反后的 umask)

    110 100 100 (按位与的结果)
  5. 最终结果转换回八进制:
    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 会进一步要求删除者满足以下条件之一:

  1. 你是该文件的属主(拥有者)。
  2. 你是该目录的属主。
  3. 你是拥有至高无版权限的 root 用户。

大白话总结:在带有粘滞位的共享房间里,每个人都可以往里面放自己的私人物品,也可以看别人的物品(如果别人允许),但是,你绝对不能扔掉或改名别人的私人物品。

3) 表现形式:底层细节里的 tT

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 权限都没有,更别提进门了。如果两个普通用户(假设是 userAuserB)想要互相"串门",也就是互相 cd 进入对方的家目录,我们需要为对方 "配钥匙"

这里有三种技术方案,按专业程度从低到高,我为你详细拆解:

方案一:简单粗暴的"大门敞开"模式 (修改 Others 权限)

这是初学者最容易想到的方法,直接利用我们学过的 chmod 命令,给家目录的"其他人(Others)"加上读和进入的权限。

实操步骤:

  1. userA 登录系统 ,开放自己的家目录:

    bash 复制代码
    chmod o+rx /home/userA
  2. userB 登录系统 ,开放自己的家目录:

    bash 复制代码
    chmod o+rx /home/userB

底层逻辑与致命缺陷:

  • 逻辑: 你们各自给自己的家目录增加了 r(看门牌号)和 x(穿透进入)的权限。
  • 缺陷: 这种做法是极其不安全的!因为 o 代表系统里的所有人 。这就好比为了让朋友来你家,你直接把自家大门给拆了。不仅 userB 能进,系统里的 userCuserD,甚至未来某个被黑客攻破的弱密码账号,全都能大摇大摆地进入你的家目录翻找文件。(强烈不推荐在公司生产环境使用)

方案二:传统的"发群名片"模式 (用户组协作)

这是 Linux 早期为了解决协同工作而设计的标准方案。既然不能向所有人(Others)开放,那我们就建立一个小圈子(Group),只向圈子里的人开放。

实操步骤(需 root 管理员介入):

  1. 管理员出面,创建一个名为 dev_team 的共享用户组:

    bash 复制代码
    sudo groupadd dev_team
  2. userAuserB 都拉进这个群里:

    bash 复制代码
    sudo usermod -aG dev_team userA
    sudo usermod -aG dev_team userB
  3. userAuserB 分别将自己家目录的属组(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(执行/穿透)、rwrxrwx-(无权限)

实操步骤(假设文件系统支持 ACL,且用户是自己家目录的属主;这种情况下通常无需 root):

  1. userA 操作:精准给 userB 颁发通行证

    bash 复制代码
    -m 代表 modify(修改), u:userB:rx 代表授予用户 userB 读取和穿透权限
    setfacl -m u:userB:rx /home/userA
  2. userB 操作:精准给 userA 颁发通行证

    bash 复制代码
    setfacl -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模型) 则是现代智能门锁的"临时指纹授权"。

相关推荐
雯宝2 小时前
3. 驱动框架(块设备)
linux
立少→万能汉编2 小时前
用“立少→超文本”写静态网页,标签<倍>
服务器·前端·javascript
静止了 所有的花开2 小时前
Ubuntu 26.04 静态 IP 配置不生效解决方法
linux·ubuntu·静态ip
笨鸟先飞,勤能补拙3 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
caimouse3 小时前
ReactOS 图形系统分析(3):显示驱动 DDI framebuf.dll
linux·运维·网络
佳児素花痴╮4 小时前
网络问题与基础理论
运维·服务器·网络
highreport4 小时前
HighReport报表工具定时调度和邮件定时发送
运维·服务器·数据库
TonyLee0174 小时前
Claude Code + DeepSeek:服务器安装与使用笔记
linux·服务器·deepseek·claude code
St_rive4 小时前
Pytest skip&&skipif跳过⽤例
运维·服务器·pytest