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 是替换,风险更大) |
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 命令 |
只把这一条命令用管理员身份跑 | 你自己的密码 | 只有这一条 |
树莓派 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 不是「执行」,而是「能不能进去」。 而且它会和 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 # 让所有人都能读
中文教程里出现 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 |
chown基本都要sudo——把东西「送给别人」本来就是个特权动作。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 秒你收获的是:「组」是登录时发给你的通知单,中间改了要重新领一张。 以后给别人加完组,记得提醒一句「重新登录再试」——不然对方一定会说你「改了没用」。
十三、常见误区
- 「
chmod和chown都是改权限」:不是一回事。chmod改「能干什么」(r/w/x),chown改「归谁」(拥有者/组)。 - 「
777最省事,能解决一切权限问题」:它能解决,但是靠把门拆掉。按需给:文件644、目录755、私密东西600/700。 - 「
sudo要 root 的密码」:要的是你自己的密码。也正因如此,root 账号可以没有密码(见第六节)。 - 「加上
-aG和写-G差不多」:差很多。-G是替换全部附加组,可能把人踢出sudo组;加组永远写-aG。 - 「目录的
x位是给脚本用的,目录用不上」:目录的x= 能不能进去,没它连cd都不行(第七节)。 - 「新建文件默认是
777,只是被改了」:文件天生不带x(最大 666),再被 umask 削掉写权限——这是刻意的安全设计(第十节)。 - 「删文件看的是文件自己的权限」:看的是「所在目录」的
w位。你在某个目录里能不能删东西,取决于你对那个目录有没有写权限。
自测三问
1. `ls -l` 输出 `-rw-r-----`,用数字写是几位数、是多少?谁能读、谁能写?(**`640`**;**拥有者能读能写,同组人只能读,其他人什么都做不了**) 2. 给一个用户「加进 sudo 组」的命令怎么写?少了哪个字母会出事?(**`sudo usermod -aG sudo 用户名`**;**少了 `a` 就变成「替换全部附加组」,可能把他从 sudo 里踢出去**) 3. 一个目录权限是 `d--x------`,你的身份是「其他人」——你能 `cd` 进去吗?能 `ls` 吗?(**都做不了**。其他人那三位是 `---`,既没有 `x` 也没有 `r`;就算有 `x` 也只是「能进」,要能 `ls` 还得有 `r`)- ☐ 下一节(4-4 Linux 操作系统的目录结构)
相关笔记
- Linux 的常用指令 —— 上一节:
ls -l、cp、chmod这些命令的用法汇总 - 启动终端机使用命令行的 Linux 指令 ——
sudo与「命令的三种出身」 - 设置 Raspberry Pi OS —— 改密码(
raspi-config里的那一项) - 你需要知道的背景知识 —— 「
sudo是权力也是风险」那条铁律 - 🍓 树莓派 · 索引 —— 全课路线图