🍓 第四章 Linux 系统管理
📄 一句话概括

Linux 是多用户系统,所以每样东西都归某个人所有、都带一套「谁能读/能改/能执行」的规矩——这一节就是把 ls -l 里那串 -rw-r--r-- 彻底讲明白,并学会用户、组、权限三类命令。这是本章唯一一节必须「会算」的内容。

📝 本节和前面几节的关系

4-1 讲过 sudo 是「以管理员身份执行一条命令」——本节要说清「管理员」到底是什么、为什么要这么设计。 4-2 里几乎所有命令都可能报 Permission denied——本节就是那个错误的解法。 这一节也会顺带回答一个你可能早就想问的问题:为什么树莓派上的 root 账号没有密码?

一、为什么 Linux 一定要分「用户」

假设不分:任何程序、任何登录进来的人,都能改系统文件、读别人的私人文件、删别人的东西。一颗病毒就能把整台机器拆了。

Linux 的答案很朴素:给每样东西记上「主人」和「允许谁做什么」。

角色 是谁 特点
root(超级用户) UID = 0 什么都能干,不受任何权限限制——所以要少用它
系统用户 UID = 1~999 不是给人登录用的,是给服务用的(如 www-data、messagebus)
普通用户 UID = ≥1000 你。权限受限,需要时用 sudo 提权
💡 一句话理解整套设计

日常用普通用户(怕手滑),需要时用 sudo 临时提权(有痕迹、可审计)。 这就是为什么树莓派的默认账号不是 root——它不是不信任你,它是给你留了一层「手滑缓冲」。

二、三个必须先分清的概念:用户、组、UID/GID

概念 大白话 说明
用户(user) 一个人/一个服务 有名有 UID
组(group) 一队人 有名有 GID;权限可以发「给整队」而不是一个个发
主组(primary group) 你「户籍所在」的组 建用户时确定,你新建的文件默认属于它
附加组(supplementary group) 你「兼属」的其他组 用来获得额外权限,如兼属 sudo 组就能提权
⚠️ 一个极易踩的坑

改完用户的组之后,必须重新登录才生效。 因为「你属于哪些组」这件事,是登录那一刻打包好交给你的——重新登录才会重新打包。 想当场生效可以敲 newgrp 组名,但它只影响当前这个终端(4-3 小节末会演示)。

三、四个「用户档案文件」:系统的户口本

这些文件都在 /etc 下(4-4 会讲这个目录的定位):

文件 装什么 能不能直接看
/etc/passwd 所有用户的基本信息 能(人人可读)
/etc/shadow 加密后的密码 不能(只有 root 能读)
/etc/group 所有组与成员 能
/etc/sudoers 谁能提权、能干什么 不能随便改(要用 visudo)

/etc/passwd 一行有七个字段,用冒号隔开:

用户名 : 密码占位 : UID : GID : 注释 : 家目录 : 登录Shell
  pi   :    x    : 1000: 1000:  ,,, : /home/pi : /bin/bash

注意第二列那个 x:它不是密码,只是个占位符,真正加密的密码在 /etc/shadow 里——这样设计是为了让 /etc/passwd 可以放心地人人可读。这个细节能帮你记住:「为什么密码不写在这儿」。

看一眼自己的那一行(很安全,passwd 人人可读):

grep "^$(whoami):" /etc/passwd

四、看:我现在是谁、属于哪些组

命令 干什么 例子
whoami 我现在的用户名 whoami
id 我的 UID、GID、所有组(一条命令全给) id
id 用户名 看别人 id root
groups 我(或某人)所属的所有组 groups、groups pi
who 现在有谁登录着 who
w 同上,但更详细(在干什么) w
last 登录历史 last \| head
uptime 开机多久 uptime
💡 最该记住的一条

id。——想知道「我是谁、能干什么」,敲它就够了。它一次给出 UID、GID 和全部组。 判断「我到底在不在 sudo 组里」,看它的输出里有没有 sudo。

五、管:建用户、改密码、加组、删用户

命令 干什么 常用写法 注意
adduser 建用户(推荐) sudo adduser alice 交互式,会一步步问你密码等;自动建家目录
useradd 建用户(底层) sudo useradd -m -s /bin/bash alice 必须加 -m 才建家目录,-s 指定 Shell;不加 -m 会建出一个「没有家目录」的怪用户
passwd 改密码 sudo passwd alice 不加用户名=改自己的(会先问旧密码)
usermod 改用户属性 sudo usermod -aG sudo alice 加组必须带 -a!见下面警告
userdel 删用户 sudo userdel -r alice -r 才会连家目录一起删;不加则保留数据
groupadd 建组 sudo groupadd dev —
gpasswd -d 把某人踢出组 sudo gpasswd -d alice dev 从组里移除(usermod -G 是替换,风险更大)
🚨 这一节最容易造成的破坏:`usermod -G` 忘了 `-a`
sudo usermod -G dev alice      # ❌ 危险:把 alice 的附加组「替换」成只剩 dev
sudo usermod -aG dev alice     # ✅ 正确:追加到 dev,其他组保留

少了 -a,这个用户可能被踢出 sudo 组,从此再也不能提权——而你还不知道为什么。记住这句:加组永远写 -aG,两个字母一起写。

推荐的建号流程(跟着敲一遍就懂):

sudo adduser alice                 # 1. 交互式建号(会问密码、姓名等)
sudo usermod -aG sudo alice        # 2. 让他也能提权(-aG,不要忘 a)
id alice                           # 3. 验收:输出里应该有 sudo

六、切换身份:su 与 sudo 的分工

命令 干什么 要谁的密码 影响范围
su - 用户名 切换成那个用户(整个终端都变) 对方的密码 一整段会话
su - 切到 root root 的密码 一整段会话
sudo 命令 只把这一条命令用管理员身份跑 你自己的密码 只有这一条
⚠️ 为什么树莓派上 `su` 用不了

树莓派 OS 的 root 账号默认没有设置密码,所以 su - 会失败(提示认证失败)。 这不是坏掉了——是官方故意的:让你走 sudo 这条路,因为 sudo(1)用你自己的密码、(2)默认 15 分钟内免重复输入、(3)每次提权都记在日志里,比一个「谁都知道密码的 root」安全得多。 想长期以管理员身份干活,用 sudo -i(开一个 root 的 Shell),退出用 exit。但不建议常用——手滑的代价太大。

sudo 的两个实用细节:

sudo -i              # 开一个 root shell(提示符会变成 #,不是 $)
sudo !!              # 给上一条命令补上 sudo —— 忘了加 sudo 时的救命招

七、ls -l 那十位:把它们拆到骨头

ls -l notes.txt
# -rw-r--r-- 1 pi pi 4096  9月 24 10:30 notes.txt

第一个字符=类型:

字符 含义
- 普通文件
d 目录(directory)
l 符号链接(link)

后面九位=三组,每组三位:

 -  rw-  r--  r--
 │   │    │    └── 其他人(others)的权限
 │   │    └─────── 同组人(group)的权限
 │   └──────────── 拥有者(owner)的权限
 └──────────────── 文件类型

每一组里的三位,位置固定是「读、写、执行」:

位置 字母 含义(对文件) 含义(对目录)
第 1 位 r 读内容 列出目录里有什么(ls)
第 2 位 w 改内容 在目录里建/删文件
第 3 位 x 当程序执行 进得去这个目录(cd)
— - 没有这个权限 同上

所以 -rw-r--r-- 读作:拥有者能读能写;同组人只能读;其他人只能读。

⚠️ 目录的 `x` 位:全章最反直觉的一条

对目录来说,x 不是「执行」,而是「能不能进去」。 而且它会和 r 分开: - 没有 x,你连 cd 都进不去(哪怕你有 r)。 - 有 x 但没 r,你进得去,但 ls 列不出内容——因为你知道具体文件名就能访问(也正因如此,一个只给 x 的目录常被用作「只能穿过、不能偷看」的通道)。

记住这条,你就理解了为什么有时「目录明明是我的,却进不去」——光看拥有者是谁没用,要看那三位里有没有 x。

八、chmod:改权限的两种写法

写法一:数字(最常用)

三个数字分别对应「拥有者、同组、其他人」,每个数字是 r(4)+w(2)+x(1) 相加的结果:

权限组合 数字 出现场景
rwx 7 4+2+1
rw- 6 4+2
r-x 5 4+1
r-- 4 4
-wx 3 2+1
-w- 2 2
--x 1 1
--- 0 无

几句口诀:4 是读、2 是写、1 是执行;加起来的数字就是那一组。所以——

数字 展开 一眼读懂 什么时候用
755 rwxr-xr-x 我能改,别人能读能进 目录、要给别人用的脚本
644 rw-r--r-- 我能改,别人只能读 普通文档、配置
600 rw------- 只有我能读能改 私钥、密码文件
700 rwx------ 只有我能进能改 私人目录(如 ~/.ssh)
640 rw-r----- 我能改,同组能读,外人不行 组内共享的敏感文件
777 rwxrwxrwx 人人可读可写可执行 几乎不该出现,见下方警告
chmod 755 myscript.sh      # 最常用的两条
chmod 644 notes.txt
chmod -R 755 mydir         # -R 递归(连里面的东西一起改)

写法二:符号(改一两位时更省事)

谁 动作 什么权限
u=拥有者 + 加 r 读
g=同组 - 减 w 写
o=其他人 = 设为 x 执行
a=三者全部 — —
chmod u+x myscript.sh        # 给拥有者添加「能执行」
chmod go-w secret.txt        # 拿掉同组和其他人的「写」
chmod a+r public.txt         # 让所有人都能读
🚨 关于 `777` 和 `chmod -R 777`

中文教程里出现 chmod 777 的频率高得离谱,几乎都是为了「让报错消失」——这是把门拆掉来治「门锁不好用」。 777 意味着任何用户、任何程序都能改这个文件。正确做法是按需给:程序要读给 644,目录要进给 755。 更别照抄 chmod -R 777 / 这种命令——那是自杀。

九、chown / chgrp:改「这东西归谁」

chmod 改的是「权限」,chown 改的是「主人」——两者完全不是一回事。

命令 干什么 例子
chown 改拥有者 sudo chown alice notes.txt
chown 用户:组 同时改拥有者和组 sudo chown alice:dev notes.txt
chown :组 只改组 sudo chown :dev notes.txt
chgrp 只改组(等价写法) sudo chgrp dev notes.txt
chown -R 连子目录一起改 sudo chown -R alice:alice ~/projects
⚠️ 两个必知点
  1. chown 基本都要 sudo——把东西「送给别人」本来就是个特权动作。
  2. chown -R 用错目录会毁掉系统:它会把整棵子树都换主人。敲之前先 ls 确认路径,和 rm -r 一个道理。

顺带说一句:chmod 自己的文件不需要 sudo(你是主人,当然能改自己东西的规矩);改别人的或系统文件才要。

十、umask:为什么新建的文件默认是 644

你有没有想过:用 touch 建的文件,权限为什么正好是 644? 这是 umask 在起作用。

规则:新建时的权限 = 最大可能权限 去掉 umask 里那些位。

类型 最大可能 减掉 umask 结果
文件 666(文件默认不给 x) umask 022 → 去掉组和其他人的 w 644
目录 777 umask 022 755
umask          # 看看当前是多少(普通用户通常 022)

记住两件事就够了:① umask 是「减号」,数字越大权限越小;② 文件天生不带 x——因为「可执行」这件事必须你明确给,不能自动产生(这是安全设计:下载来的文件不会自己变成程序)。

十一、动手 Demo:亲手造一个「权限实验」

在树莓派上按顺序跑完这八步(每一步都对应上面某一节):

# 0. 我是谁、在哪些组
id

# 1. 造一个实验场
mkdir -p ~/perm_lab && cd ~/perm_lab
echo "hello" > a.txt
echo "#!/bin/bash" > b.sh
echo 'echo "我跑起来了"' >> b.sh

# 2. 看默认权限(应该 644 / 644)
ls -l

# 3. 让它可执行,再跑
chmod 644 a.txt        # 明确写一遍(和默认一样,只是体验)
chmod 755 b.sh
./b.sh                 # 成功执行 → 说明 x 位生效了

# 4. 故意把 x 去掉,再看会怎样
chmod 644 b.sh
./b.sh                 # 应该报 Permission denied —— 这就是 4-2 里那个错的来源

# 5. 目录的 x:验证「进不去」
mkdir secret && echo "里面" > secret/inner.txt
chmod 600 secret       # 去掉 x
cd secret              # 应该被拒

# 6. 只给 x 不给 r:进得去但列不出
chmod 100 secret
cd secret && ls        # 应该能进,但 ls 报权限不足
cd ..

# 7. 数字改法 vs 符号改法,等价验证
chmod 700 secret
ls -ld secret          # rwx------
chmod u=rwx,go= secret
ls -ld secret          # 还是 rwx------

# 8. 看 umask 与新建默认值的关系
umask
touch brand_new.txt && mkdir brand_new_dir
ls -ld brand_new.txt brand_new_dir

看到什么算成功:

步骤 预期
0 uid=1000(你的名字)、gid=1000、组列表里含 sudo
2 a.txt 和 b.sh 都是 -rw-r--r--
3 ./b.sh 打印「我跑起来了」——没有 x 位时它会拒绝,有 x 位就跑了,这是本节的核心因果
4 bash: ./b.sh: Permission denied —— 记住这句话,它就是 chmod +x 存在的理由
5 cd: secret: 权限不够
6 cd 成功(提示符里出现 secret),但 ls 报 Permission denied —— 这就是「x 管进、r 管看」的实证
7 两次 ls -ld 输出一致(都是 drwx------)——数字与符号写法等价
8 umask 输出 0022;新建文件是 644、新建目录是 755

最后清理(别忘了:删不完就说明权限还没玩明白,正好再练一次):

cd ~ && chmod -R 700 ~/perm_lab && rm -r ~/perm_lab
ls ~ | grep perm_lab || echo "清理干净 ✅"

「读结果」提示:第 4 步和第 6 步是这一节的灵魂——它们把「报错」变成了一次可重复、可解释的实验。以后再看到 Permission denied,你的反应应该是:「哦,少了个位」,而不是「为什么坏了」。

十二、30 秒实验

验证「改完组必须重新登录才生效」。

# 1. 先看一眼现在的组
groups

# 2. 建一个测试组,把自己加进去
sudo groupadd dtest
sudo usermod -aG dtest "$USER"

# 3. 立刻再看一次组
groups          # ← 关键:这里多半看不到 dtest!
id -nG          # 同上

# 4. 让它在当前终端立即生效
newgrp dtest
groups          # 这次有了
exit            # 退出这个临时组环境

# 5. 清理
sudo gpasswd -d "$USER" dtest
sudo groupdel dtest

你会看到:第 3 步 groups 看不到 dtest,第 4 步 newgrp 之后就看到了。

这 30 秒你收获的是:「组」是登录时发给你的通知单,中间改了要重新领一张。 以后给别人加完组,记得提醒一句「重新登录再试」——不然对方一定会说你「改了没用」。

十三、常见误区

自测三问 1. `ls -l` 输出 `-rw-r-----`,用数字写是几位数、是多少?谁能读、谁能写?(**`640`**;**拥有者能读能写,同组人只能读,其他人什么都做不了**) 2. 给一个用户「加进 sudo 组」的命令怎么写?少了哪个字母会出事?(**`sudo usermod -aG sudo 用户名`**;**少了 `a` 就变成「替换全部附加组」,可能把他从 sudo 里踢出去**) 3. 一个目录权限是 `d--x------`,你的身份是「其他人」——你能 `cd` 进去吗?能 `ls` 吗?(**都做不了**。其他人那三位是 `---`,既没有 `x` 也没有 `r`;就算有 `x` 也只是「能进」,要能 `ls` 还得有 `r`)

相关笔记