When working with Linux filesystems, you might encounter situations where default ACLs set on a parent directory don't automatically propagate to existing child items. This happens because default ACLs only affect:
- Newly created files/directories
- Items moved into the directory
- Not pre-existing content
The most efficient way to apply parent directory's default ACLs recursively is:
find /path/to/parent -type d -exec setfacl -m d:u:phptutor:rwx {} \;
find /path/to/parent -type f -exec setfacl -m u:phptutor:rw {} \;
Breaking down what these commands do:
# For directories (-type d):
# -m : modify ACL
# d:u:phptutor:rwx : sets default ACL for user phptutor
# {} : placeholder for each found directory
# For files (-type f):
# Removes the 'x' permission as it's typically unnecessary for files
For more complex scenarios where you want to exactly copy all default ACLs:
getfacl /path/to/parent | grep '^default' | setfacl -d -M- /path/to/target
For directories with thousands of files, consider this optimized version:
find /path/to/parent -type d -print0 | xargs -0 -P 4 -I {} setfacl -m d:u:phptutor:rwx {}
find /path/to/parent -type f -print0 | xargs -0 -P 8 -I {} setfacl -m u:phptutor:rw {}
Key optimizations:
- -print0 and -0 handle filenames with spaces
- -P enables parallel processing (4 for dirs, 8 for files)
After applying ACLs, verify with:
getfacl /path/to/parent/some_child
Common issues to check:
- Ensure parent directory actually has default ACLs (look for 'default:' lines in getfacl output)
- Check for conflicting ACL masks that might override permissions
- Verify the filesystem supports ACLs (ext4, xfs, etc.)
When working with Access Control Lists (ACLs) in Linux, you might encounter situations where newly set default ACLs on a parent directory don't automatically apply to existing files and subdirectories. This happens because default ACLs only affect newly created items.
$ getfacl parent_dir/
# file: parent_dir/
# owner: user
# group: group
user::rwx
group::r-x
other::r-x
default:user:phptutor:rwx
The most effective way to apply default ACLs to existing files is using setfacl
with the --recursive
flag and the --set-file
option:
$ getfacl parent_dir/ | setfacl --recursive --set-file=- parent_dir/
This command:
- Gets the current ACLs of the parent directory
- Pipes them to setfacl
- Applies them recursively to all files and subdirectories
For more control over the process, you can combine find
with setfacl
:
$ find parent_dir/ -type d -exec setfacl -m d:u:phptutor:rwx {} \;
$ find parent_dir/ -type f -exec setfacl -m u:phptutor:rwx {} \;
Always verify the changes with getfacl:
$ getfacl parent_dir/subdir/file.txt
# file: parent_dir/subdir/file.txt
# owner: user
# group: group
user::rw-
user:phptutor:rwx
group::r--
mask::rwx
other::r--
- Backup important data before running recursive ACL operations
- Consider using
--test
flag first to see what changes would be made - Be aware of performance impact when processing large directory trees
- Default ACLs (d:) only apply to directories, not files
For regular maintenance, you might want to create a script:
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 directory"
exit 1
fi
TEMP_ACL=$(mktemp)
getfacl "$1" > "$TEMP_ACL"
find "$1" -exec setfacl --set-file="$TEMP_ACL" {} \;
rm "$TEMP_ACL"