The simple, stupid answer:
You can shorten your sequence of commands a little by combining the first n–1 of them:
setfacl -m u:colleague:x /rather /rather/long /rather/long/path /rather/long/path/to /rather/long/path/to/the
setfacl -m u:colleague:xr /rather/long/path/to/the/directory
An “obvious” warning:
Even if you own the target (leaf) directory,
you need to have execute (traverse) access to every directory in the path.
If there’s any directory that you don’t have access to and you don’t own,
you’re out of luck.
(You need to assume an identity (i.e.,
root or the owner of the directory)
that lets you give yourself access, or persuade somebody who has the power to do so.
That’s out of the scope of this question.)
But, if there are intermediate directories that you own but don’t have access to
(e.g., somebody has done
chmod 0), you need to give yourself access from the top down.
The answer: (TL;DR)
I made the above point because this works from the bottom up:
while branch="$(dirname "$branch")"
setfacl -m u:colleague:x "$branch" || break
if [ "$branch" = / ]
setfacl -m u:colleague:xr "$leaf"
Optionally, you can hide any error messages from
setfacl by adding
If you have a pathological situation where you own
/rather/long/path/to, but not
/rather/long/path (but its permissions are open), remove the
|| break after the
setfacl, because you need to keep climbing the tree
after getting the error on
setfacl … /rather/long/path.
Otherwise, if you are not
root, you could remove the
if [ "$branch" = / ] test, because the loop will terminate when you reach a directory level
where you can’t run
(But that’s not a great idea; if you save this as a script,
you will someday run it as
root, and then you’ll have an infinite loop.)
It goes without saying that, if you make this a script, the directory path and the colleague’s name should be parameters.