
























作为一个Mac开发者,我遇到了一个问题:
我的项目要用到443端口(就是网址https默认用的那个端口)。在Mac上,只要是1024以下的端口,都必须用管理员权限才能用。所以我每次启动项目都得加sudo:
sudo npm start
用着用着就习惯了,后来连build项目的时候也顺手加了sudo:
sudo npm run build
结果有一天,我忘了加sudo直接运行build,报错了:
Error: EACCES: permission denied, open 'dist/index.html'
翻译成人话就是:没有权限,没法操作dist文件夹里的文件。
我用ls -la命令看了下:
ls -la
# 输出显示:drwxr-xr-x root staff 192 5 20 10:30 dist
发现问题了!dist文件夹的所有者是root(系统管理员),难怪普通用户没法往里写东西。
原因很简单:我之前一直用sudo跑build,生成的dist文件夹自然就归root管了。
解决办法也简单:
sudo chown -R $(whoami):staff dist
这条命令的意思是:把dist文件夹的所有权,从root改回给当前用户。
这个小问题让我决定好好研究一下Mac的权限系统,今天就把它彻底搞懂。
sudo就是"借用管理员身份"来执行命令。
打个比方:
基本用法:
sudo 要执行的命令
最常见的情况:
/usr/local)# 用管理员身份执行命令
sudo npm install -g some-package
# 切换到管理员账号(相当于变成root用户)
sudo su
# 切换到管理员账号,同时进入root的目录
sudo su -
# 用管理员身份编辑文件
sudo vim /etc/hosts
# 查看当前用户能执行哪些sudo命令
sudo -l
说实话,这几个命令初学者容易搞混,我简单总结下:
| 命令 | 通俗解释 | 你现在在哪 | 你是谁 |
|---|---|---|---|
sudo 命令 |
临时用管理员身份干一件事 | 还在自己目录 | 干完就变回自己 |
sudo su |
变成管理员,但还在当前目录 | 在自己目录 | 现在是管理员 |
sudo su - |
彻底变成管理员 | 在管理员的家目录 | 现在是管理员 |
简单记:日常用sudo 命令就够了,除非你真的需要一直当管理员。
Mac上的端口号分三六九等:
443端口就属于第一类——特权端口。因为这是https网站默认用的端口,Mac觉得这么重要的端口,不能让普通程序随便占用。
# 查看443端口的使用情况
sudo lsof -i :443
# 输出示例
# node 12345 user 12u IPv4 0x123456789 0t0 TCP *:https (LISTEN)
有几种替代方案:
方案一:用其他端口开发
比如用3000、8080这些普通端口,等部署到服务器再用443
方案二:用端口转发
# 把本地的8080端口伪装成443
echo "rdr pass on lo0 inet proto tcp from any to any port 443 -> 127.0.0.1 port 8080" | sudo pfctl -ef -
方案三:用管理员权限运行Node
# 给Node特殊权限(有点复杂,新手不推荐)
sudo chown root $(which node)
sudo chmod u+s $(which node)
ls -la
# ls = list(列出文件)
# -l = long format(显示详细信息)
# -a = all(包括隐藏文件)
假设看到这一行:
drwxr-xr-x 12 root staff 384 5 20 10:30 dist
拆开来看:
| 部分 | 含义 | 通俗解释 |
|---|---|---|
d |
文件类型 | d表示文件夹,-表示普通文件 |
rwxr-xr-x |
权限信息 | 谁能读、写、执行这个文件 |
12 |
链接数 | 不用太关心 |
root |
所有者 | 这个文件归谁管 |
staff |
所属组 | 这个文件归哪个小组管 |
384 |
大小 | 文件有多大 |
5 20 10:30 |
修改时间 | 最后修改时间 |
dist |
文件名 | 文件叫啥 |
rwx分别代表:
rwxr-xr-x可以分成三组:
rwx:文件所有者有啥权限(可读可写可执行)r-x:同组的用户有啥权限(可读可执行,但不能修改)r-x:其他用户有啥权限(可读可执行,但不能修改)简单记个口诀:r=4,w=2,x=1
比如rwxr-xr-x转成数字:
所以rwxr-xr-x = 755
常用的权限组合:
chown = change owner(改变所有者)
就是把文件/文件夹的"主人"换成别人。
# 把文件的所有者改成张三
sudo chown 张三 文件名
# 把文件的所有者改成张三,所属组改成staff
sudo chown 张三:staff 文件名
# 把文件夹及其里面的所有文件都改掉(-r就是递归)
sudo chown -R 张三:staff 文件夹名
sudo chown -R $(whoami):staff dist
拆解一下:
sudo:用管理员权限执行(只有管理员才能改别人的文件)chown:改变所有者的命令-R:递归,把dist里面的所有文件都改了$(whoami):当前登录的用户名(我的是zhangsan):staff:所属组改成staff(Mac普通用户默认都在这个组)dist:要修改的文件夹整条命令的意思就是:把dist文件夹以及里面所有文件的"主人",从root改成当前用户,同时把所属组改成staff。
# 只用当前用户名
sudo chown -R $USER:staff dist
# 只改所有者,不改所属组
sudo chown -R $USER dist
# 只改所属组,不改所有者
sudo chown -R :staff dist
# 把整个当前目录都改回来(有时候很有用)
sudo chown -R $USER:staff .
# 正常build报错
npm run build
# 报错:permission denied
# 查看当前目录所有文件
ls -la
# 发现dist目录是root的
# drwxr-xr-x root staff ... dist
# 把dist还给当前用户
sudo chown -R $(whoami):staff dist
# 验证一下
ls -la
# 现在显示 drwxr-xr-x zhangsan staff ... dist
npm run build
# 成功了!
ls -la看看文件主人,很多权限问题一眼就能发现chmod 777解决问题,这是图省事埋大坑配置npm全局安装不需要sudo:
# 设置npm全局安装到自己的目录
npm config set prefix '~/.npm-global'
# 把这个目录加到PATH
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc
# 重新加载配置
source ~/.zshrc
# 以后就可以直接 npm install -g 包名,不用sudo了
权限问题的本质:文件有主人,谁的主人谁才能改。
排查步骤:
ls -la看看文件主人是谁sudo chown -R 自己:staff 文件夹改回来预防措施:
一个小习惯,让我绕了个大弯,但也因祸得福,把Mac的权限系统彻底搞懂了。
以后再遇到"Permission denied",我就知道:
ls -la)whoami)sudo chown)希望这篇文章能帮你少走弯路,遇到类似问题不慌不忙,几分钟就搞定!
如果下次遇到权限问题,先想这三步:
搞定!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。