If I have a directory with default ACL entries assigned to it, but some or all of its descendant files and sub-directories have access or default ACLs that do not agree with those defaults, how do I recursively (re)apply those default ACL entries to all descendants? There is a qualification. I wish to entirely replace all existing descendant ACLs except for the existing execute status of files. The intent otherwise is that all descendants should have the ACLs they would have if newly created in their current location.

Rogach asked "How do I set permissions recursively on a dir (with ACL enabled)?" but was looking to add a new ACL entry recursively rather than (re)applying an existing default ACL. Although not asked for by Rogach, Franklin Piat's answer to that question also offers a solution to my question, but I believe his solution is flawed. Piat suggests this pair of commands:

find . -mindepth 1 -type d| xargs -n 50 setfacl -b --set-file=<(getfacl . | sed -e 's/x$/X/')
find . -mindepth 1 -type f| xargs -n 50 setfacl -b --set-file=<(getfacl . | grep -v '^default:' | sed -e 's/x$/X/')

The flaws that I want to fix:

  • The current directory's access ACL is being propagated to descendants instead of its default ACL, which is not how I understand ACLs should work.
  • The execute bit is cleared for all files (sed is ineffective).
  • Typical sudoer policies prevent process substitution from working when root privileges are required. See "closefrom_override" option for sudoers(5).

Ideally I would also only need one command line to accomplish this one task.

  • A recommendation: when you have a hacky solution to something and believe there's a better way, self-answer the question. Don't include the hacky solution in your question. Mention in the question that you have a hacky solution which you're posting as an answer and that you're hoping for a better way; mention in the answer that it's a hacky solution and list its faults (but don't put a question mark in your answer). It makes for a lot less reading in order to understand the question. And then if your answer really is the best way, the votes can show that.
    – Wildcard
    Dec 13, 2017 at 7:31

1 Answer 1


I have come up with this ugly, inefficient solution but surely there's a better way:

( cd '/some/dir' && sudo find . -mindepth 1 -path './leave/alone' -prune -o \( -type d -exec bash -c 'getfacl -cd . | sed -nre "p;/^\$/!s/^/default:/p" | setfacl -bM - "{}"' \; \) -o \( -type f -exec bash -c 'getfacl -cd . | sed -re "/^#/!s/x\$/X/" | setfacl -bM - "{}"' \; \) )

Some comments about that monstrosity:

  • I've included a sub-directory exclusion to demonstrate that frequent requirement.
  • The cd eliminates the error-prone repetition of the source directory path and the outer parentheses make that change temporary.
  • The use of bash is needed because "-exec" doesn't allow pipelines. It also avoids that '!' character invoking history substitution and resulting in the infamous “event not found” error.
  • For sub-directories we must apply the source default ACLs as both access ACLs and default ACLs.
  • For files we must apply source default ACLs as access ACLs but apply no default ACLs at all if we wish to avoid the “Only directories can have default ACLs” warnings from setfacl.
  • For files we need to replace 'x' permissions from the source default ACLs with 'X' in order that we don't end up forcing all files to become executable. This solution also preserves the executable status of existing files, but only because we use “-bM -” rather than “--set-file=-” with setfacl.
  • This command line is very inefficient because I don't know of a way to use “-exec ... +” or xargs instead of “-exec ... \;”.
  • This command line works, but beware that descendant files get ACLs that are effectively equivalent but not technically equivalent to what occurs when newly creating a new descendant file.

The "Unix philosophy" is fantastic, but the task I'm trying to accomplish is needed too often for it to require such an unwieldy command line. Is there a better way aside from lobbying for additional features in setfacl?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .