如何获取用户对文件树中嵌套文件/目录的有效权限(传统权限+ACL)
如何查看指定用户/组对嵌套文件树的完整有效权限(含ACL)
刚好我之前折腾过类似的需求——要精确拿到指定用户/组对嵌套文件树的完整有效权限集合(包括传统权限和ACL的叠加),而不是简单判断能不能访问。这里给你几个实用的方案,从手动分析到自动化脚本都有:
方法一:用自动化脚本批量计算(推荐)
如果要遍历整个嵌套文件树,手动分析每个文件的ACL太耗时,我写了个bash脚本可以自动帮你计算指定用户的有效权限:
#!/bin/bash # 参数检查 if [ $# -ne 2 ]; then echo "用法: $0 <用户名/UID> <目标路径>" exit 1 fi TARGET_USER="$1" TARGET_PATH="$2" # 获取目标用户的UID和所有组ID(主组+附加组) USER_UID=$(id -u "$TARGET_USER") USER_GIDS=$(id -G "$TARGET_USER") # 遍历所有文件/目录(处理含空格的文件名) find "$TARGET_PATH" -print0 | while IFS= read -r -d '' item; do echo "=== 文件/目录: $item ===" # 获取完整ACL信息 FACL_OUTPUT=$(getfacl -p "$item") echo "$FACL_OUTPUT" # 初始化有效权限为0(无权限) EFFECTIVE_PERMS=0 # 1. 优先匹配用户专属ACL条目 USER_ACL=$(echo "$FACL_OUTPUT" | grep "^user:$USER_UID:" || echo "$FACL_OUTPUT" | grep "^user:$TARGET_USER:") if [ -n "$USER_ACL" ]; then PERM_STRING=$(echo "$USER_ACL" | awk -F: '{print $3}') PERM_NUM=0 [[ $PERM_STRING == *r* ]] && PERM_NUM=$((PERM_NUM + 4)) [[ $PERM_STRING == *w* ]] && PERM_NUM=$((PERM_NUM + 2)) [[ $PERM_STRING == *x* ]] && PERM_NUM=$((PERM_NUM + 1)) EFFECTIVE_PERMS=$PERM_NUM else # 2. 匹配用户所属组的ACL条目,取最大权限 MAX_GROUP_PERM=0 for GID in $USER_GIDS; do GROUP_ACL=$(echo "$FACL_OUTPUT" | grep "^group:$GID:" || echo "$FACL_OUTPUT" | grep "^group:$(id -gn "$GID"):") if [ -n "$GROUP_ACL" ]; then PERM_STRING=$(echo "$GROUP_ACL" | awk -F: '{print $3}') PERM_NUM=0 [[ $PERM_STRING == *r* ]] && PERM_NUM=$((PERM_NUM + 4)) [[ $PERM_STRING == *w* ]] && PERM_NUM=$((PERM_NUM + 2)) [[ $PERM_STRING == *x* ]] && PERM_NUM=$((PERM_NUM + 1)) if [ $PERM_NUM -gt $MAX_GROUP_PERM ]; then MAX_GROUP_PERM=$PERM_NUM fi fi done EFFECTIVE_PERMS=$MAX_GROUP_PERM # 3. 如果组权限为空,匹配other权限 if [ $EFFECTIVE_PERMS -eq 0 ]; then OTHER_ACL=$(echo "$FACL_OUTPUT" | grep "^other:") PERM_STRING=$(echo "$OTHER_ACL" | awk -F: '{print $2}') PERM_NUM=0 [[ $PERM_STRING == *r* ]] && PERM_NUM=$((PERM_NUM + 4)) [[ $PERM_STRING == *w* ]] && PERM_NUM=$((PERM_NUM + 2)) [[ $PERM_STRING == *x* ]] && PERM_NUM=$((PERM_NUM + 1)) EFFECTIVE_PERMS=$PERM_NUM fi fi # 转换为rwx字符格式 PERM_CHAR="" [[ $((EFFECTIVE_PERMS & 4)) -ne 0 ]] && PERM_CHAR+="r" || PERM_CHAR+="-" [[ $((EFFECTIVE_PERMS & 2)) -ne 0 ]] && PERM_CHAR+="w" || PERM_CHAR+="-" [[ $((EFFECTIVE_PERMS & 1)) -ne 0 ]] && PERM_CHAR+="x" || PERM_CHAR+="-" echo "→ 目标用户 $TARGET_USER 的有效权限: $PERM_CHAR (数字: $EFFECTIVE_PERMS)" echo "" done
使用步骤:
- 把脚本保存为
calc_effective_acl.sh - 赋予执行权限:
chmod +x calc_effective_acl.sh - 运行脚本:
./calc_effective_acl.sh john /path/to/your/file/tree
注意事项:
- 运行脚本需要有足够权限读取目标路径下所有文件的ACL(比如用root身份执行)
- 脚本会自动处理含空格的文件名,同时计算目录的
x权限(代表能否进入目录)
方法二:手动分析单个文件的有效权限
如果只是检查单个文件/目录,可以用getfacl结合手动判断:
- 先查看目标文件的完整ACL:
getfacl -p /path/to/file
输出会包含传统权限对应的ACL条目(user::xxx、group::xxx、other::xxx)和额外的ACL规则(比如user:john:rwx)。
- 获取目标用户的UID和所有组ID:
id -u john # 获取UID id -G john # 获取所有组ID(主组+附加组)
- 按照ACL优先级计算有效权限:
- 优先匹配用户专属ACL:如果有
user:<用户名/UID>:xxx的条目,直接用这个权限 - 其次匹配组ACL:在用户所属的所有组中,取权限最大的那个
group:<组名/GID>:xxx条目 - 最后匹配other权限:如果前面都没有匹配到,用
other::xxx的权限
- 优先匹配用户专属ACL:如果有
举个例子:
假设文件的ACL输出是:
# file: test.txt # owner: root # group: root user::rw- user:john:rwx group::r-- group:devs:rw- other::r--
目标用户john属于devs组,那么他的有效权限是rwx(因为匹配到了专属ACL条目)。
内容的提问来源于stack exchange,提问作者Stilez
相关产品推荐
相关产品推荐

