有的时候我们多人在一台 linux 服务器上操作同一个目录,这时候经常出现权限错误,比如一个用户上传的文件其他用户编辑不了。

解决这个问题的方案主要是 SGID(Set Group ID) 和 acl。前者决定新建在文件属于哪个组,后者决定新建的文件给这个组默认什么权限。
这样我们只要将允许操作的用户都加入到这个组,所有用户都可以操作目录下文件了。

解决文件所属组问题 SGID

当一个目录设置了 SGID 位后,任何人在该目录下创建的子目录或文件,都默认继承父目录的的所属组,而不是使用创建者自己的组。

# 创建组(如果还没有的话)
sudo groupadd project_team

# 将相关用户加入组
sudo usermod -aG project_team user1
sudo usermod -aG project_team user2

# 更改目录所属组
sudo chgrp -R project_team /path/to/your/dir

# 给目录设置 SGID
# 2 表示 SGID 位,也可以用 g+s
sudo chmod -R 2775 /path/to/your/dir

解决文件权限问题(umask 或者 acl)

上面解决了新建的文件都继承了父目录的组,但是这个组具有哪些操作权限并不会继承。一个用户创建了一个新文件,可能没有给这个组读写权限。
解决这个问题的方法有两种
一种是 umask
在每个用户的 ~/.bashrc~/.profile 中添加:

umask 002

这个这个用户创建的新文件就是 664 权限。
第二种是 acl
umask 方式需要每个用户都自己修改自己的 umask 配置,或者改变全局 umask 配置,相对来说比较繁琐或者影响范围大。
Default ACL 给了另一种解决方案,可以给目录配置一个权限模版,这个目录下的所有文件都使用这个权限。

# 1. 确保目录本身及其现有内容对组可见、可写
sudo setfacl -R -m g:project_team:rwx /shared/project

# 2. 重新加强默认继承权限 (确保包括目录权限 X)
# -m: 修改权限
# d:  代表 default (默认),这是关键
# g:  代表 group (组)
# 默认给 `project_team` 组分配 `rwx`(读、写、执行)权限
sudo setfacl -d -m g:project_team:rwx /shared/project

# 3. 同时也给 mask 设一个默认值(可选但推荐)
sudo setfacl -d -m m::rwx /shared/project

其它问题

在 scp 和 rsync 时,可能会显示的设置文件权限,这样会和 ACL 冲突。
所以使用 rsync 上传时可以加入这些参数

参数 全称 作用描述 禁用后的效果
--no-p --no-perms 不保留权限位 服务器新文件的权限将由其父目录的 Default ACL 或系统的 umask 决定,而不是照搬你本地的 755644
--no-o --no-owner 不保留属主 rsync 不会尝试把文件的拥有者(UID)改成和你本地一样。新文件的拥有者通常就是执行 rsync 登录的那个用户。
--no-g --no-group 不保留属组 忽略本地文件的组信息(GID)。由于你设置了 SGID,禁用此项后,新文件的属组会强制继承父目录的组,非常稳。
--no-t --no-times 不保留修改时间 服务器文件的“修改时间”会更新为当前同步的时间,而不是保持本地文件原始的修改时间。