目录明明有读的权限,为什么用cd还是进不去?
目录明明有读的权限,为什么用cd还是进不去?
想象一下一个场景,你刚写完了一个脚本youniu.sh,然后兴致勃勃点击回车键执行,屏幕上弹出一行文字bash: ./deploy.sh:Permission denied,这时候你可能还一脸茫然:“不是哥们,我创建的脚本我没权限?”。
然后上网一搜,有些人说:“执行chmod 777就可以了 ”,这时候你照着大佬说的做了一遍,果然脚本立马跑起来了,没有任何的报错问题。
然后还有另一种情况更是令人困惑,一些目录你可能觉得有权限,ls 也能列出里面的文件名,但是你用cd一进去就报错,这种情况大部分都会是一脸懵,“这究竟是机魂大不悦,还是电脑在抽风?”。
这一章主要讲明白一件事情,把权限从头到尾讲清楚,读完之后你会觉得ls -l那串符号他们其实排的挺合理。
一、系统眼里的你是谁
在开始之前先明白一些事情:系统认为的你到底是谁。
Linux不同于去认你的用户名,它认的是UID(即用户标识符)。每个用户在被创建时都会被分配到一个数字编号,即使改用户名这个编号也不会改变。
编号被分为三组:
| UID范围 | 身份 | 用途 |
|---|---|---|
| 0 | root | 超级管理员,想干什么干什么为所欲为 |
| 1到999 | 系统用户 | 给服务程序用,不是给人登录 |
| 1000及以上 | 普通用户 | 你和我这样的日常账号 |
在身份里面普通用户能自由操作的范围基本限制在自己的目录里面,一般动其他用户的文件基本会被拦着,这就是你第一次尝试编辑/etc下的配置文件时,系统通常都会报错的原因。
如果你想确认自身的身份,三条命令就够用了
- 看用户名-
whoami - 看UID和所属组-
id - 看自己加入了哪些组-
groups

二、把服务器想象成一栋办公大楼
接下来就是比较关键的几个地方。
现在可以想象一下,Linux系统就是一个办公大楼,楼里面划分出来了几个区域
| 区域 | 权限身份 | 谁能进 |
|---|---|---|
| 大楼大厅 | others(其他人) | 任何人都能进 |
| 员工办公区 | group(所属组) | 本组成员能进 |
| 私人办公室 | owner(所有者) | 只有文件的所有人能进 |
| 机房 | root(超级管理员) | 权限最高者能进 |
任何人做到了一份文件前面,系统都会按照这样的顺序问:
- 你是主人吗?
- 你是同组的人员吗?
- 还是过路的访客?
当哪一层匹配他就会给你那一层的钥匙。
主组它通常和用户名同一个名,你创建的文件默认归属于它。附属组是你额外加入的组,用来跨部门共享资源。
三、进门之后决定你能干什么:rwx
身份被确认后,才轮到「你能做什么」。文件和目录都写明了三个动作:r(read,读)、w(write,写)、x(execute,执行)。
其中的关键在于,很多同样的字母放在文件和目录上含义就完全不同。这一点入门的时候很容易被忽略,也就是新手容易混乱的源头
| 权限 | 对文件的解释 | 对目录的解释 |
|---|---|---|
| r | 读文件的内容 | 列出文件下的目录名称 |
| w | 修改文件的内容 | 新建、删除、重命名目录内的文件 |
| x | 作为程序执行 | 进入这个目录(cd) |
这个表可以截图保存下来。还记得一开始问的问题吗?答案就在最后一行里
四、如何看懂ls -l的那一串天书
执行ls -l(简写成ll也行),你会看到这样的一行;

我们就拿第一个来举例(其实两个也没差别)
drwxrwxr-x 3 kali kali 4096 9月 9日 21:15
我们从左往右边读拆开来看。
- 第一位
d的位置是文件类型,总共有三种类型:-代表普通文件,d代表目录,l代表链接。 - 第二位
rwx的位置是所有者的权限,所有者对该目录列举文件下的目录名称、修改目录下文件、进入目录的权限 - 第三位
rwx的位置是所属组的权限,所属组对该目录具有列举文件下的目录名称、修改目录下文件、进入目录的权限 - 第四位
r-x的位置是其他人的权限,其他身份的用户可以对该目录进行列出文件下的目录名称、进入该目录的权限
五、回到开头:为什么有r还是进不去?
现在我创建了一个文件,用ls -l查询权限,发现权限是drw-r--r--(数字 644)

因为我有读的权限r,所以我现在可以用ls 有牛把里面的文件名给列出来

但是仔细看上面还写了一只有牛/有牛:权限不够,在尝试用cd 一只有牛

这次是直接告知我的权限不够了。
原因就是第三章那个表格的最后一行。对于一个目录来说,r只能让你在门口望一眼看看里面大概有什么东西,只有x才能决定你能不能进这道门
文件名打得出来,是因为读名单只需要r,后面的那个cd失败是因为要触碰到这个文件本身、要穿过这道们就必须要x。
接下来就自己动手试试吧:
mkdir demo && touch demo/a.txt
chmod 644 demo
ls demo # 打出 a.txt,同时报错:无法访问 'demo/a.txt':权限不够
cd demo # cd: 权限不够:demo
想让别人能进来翻阅目录,数字至少给到 5(r-x);要能在里面增删文件,需要 7(rwx)。目录缺了 x,等于把门锁上却给了你一张名单。
六、修改权限:chmod的两种用法
我们已经了解了基本原理,现在直接进行chmod修改权限应该也是得心应手,chmod的修改方式分为两种写法:数字法和符号法。
数字法
把我们学过的r、w、x分别设为4、2、1,一组的权限就是三个数字的和。
如下:
rwx=7 rw-=6 r-x=5 r--=4
把这些按照顺序拼起来就能得到三位数的指令。
chmod 644 notes.txt # 普通文件
chmod 755 myscript.sh # 脚本或目录
chmod 600 secret.txt # 私密文件,如密钥
chmod 777 anything # 所有人可读可写可执行,危险
在日常最常用的几个组合为这四个
为什么 777 危险?它意味着任何能登录这台机器的人,都能读、能改、能执行你的文件。放在一台多人共用的服务器上,这相当于把自家门锁拆了,还对外公告了一声。
符号法
这种应用方式更适合精准的给某一位改变权限,主要是方便u指的是所有者,g指的是所属组, o指的是其他人,a指的是所有人。
方法大概是这样:
chmod u+x file # 给主人加执行权限
chmod g-w file # 去掉组的写权限
chmod o=r file # 其他人设为只读
权限要用最小原则,要刚好够用,能不给就不给
七、人不对?就用chown解决问题。
还有一种比较少见的情况,你的权限是你需要的内容,但是你用的时候却发现归属者不太对,这时候就要请出chown了。
它就这么用:
chown kali test.txt # 只改所有者
chown kali:dev test.txt # 同时改所有者和所属组
chown -R kali:dev /var/www # 递归修改整个目录
这个-R是什么意思?
他会把目录内部的所有文件和子目录一并改,执行前务必确认路径正确,这个命令用错了改权限会很麻烦。
八、用户和组管理速查表
这张表建议保存一下,在碰到权限问题可以按照需求一步步排查,或者按照需求操作。
| 场景 | 命令 |
|---|---|
| 查看当前用户名 | whoami |
| 查看 UID 和所属组 | id |
| 看自己在哪些组 | groups |
| 谁在线 / 谁在干什么 | who / w |
| 创建新用户 | sudo adduser 用户名 |
| 修改用户密码 | sudo passwd 用户名 |
| 删除用户(保留家目录) | sudo deluser 用户名 |
| 删除用户(连带家目录) | sudo deluser --remove-home 用户名 |
| 强制注销某个用户 | sudo loginctl kill-user 用户名 |
| 创建组 | sudo addgroup developers |
| 把用户加入组 | sudo adduser xiaoming developers |
| 把用户移出组 | sudo deluser xiaoming developers |
| 删除组 | groupdel developers |
所有的用户信息一般都在/ect/group这个文件里。直接用cat就可以查看
在工作环境可以给一组同事开共享目录,建一个新组把大家拉进去,再把目录的所属组改成它。以后有人离职,移出组就一次性收回全部权限。
九、下次遇见权限不够的问题,找这几步走
别再第一时间甩一个 chmod 777 了。按这三步排查,基本都能定位到根因。
第一步先看自己是谁。 执行 id,看清楚 UID 和所属组,判断系统把你放到了哪一层。
第二步看目标属于谁。 ls -l 文件名,确认所有者和所属组,再看你要的那个动作在不在对应的三位上。
最后一步,缺什么补什么。缺执行就 chmod +x,归属不对就动 chown。一次给满确实省事,后面收拾残局也确实麻烦。
十、结尾
回到开头那个「权限不够」
看懂了权限模型后,下次再遇见它,第一反应就输入ls -l看一眼,确认自己在那一层,最后只补上缺少的那个权限,这比777要安全许多。
系统的权限拦截在拦你的同时也栏住了不怀好意的人,一个处处都挂着666和777的机器风险极大,只需要普通账号就能拿捏,剩下的基本和不设防没区别。