20

I need to set read and write permissions for root user to directory subfolderN and all its parent folders till root.

I can do it by hands:

$ sudo chmod +rx /root/subfolder1/subfolder2/subfolderN
$ sudo chmod +rx /root/subfolder1/subfolder2
$ sudo chmod +rx /root/subfolder1
$ sudo chmod +rx /root

But if N is big I am tired. How to do automatically by one command?

1
  • You should really not make /root world readable. Jun 15 '18 at 13:23
27

This can be done easily in the shell, starting in the subdir and moving upwards:

f=/root/subfolder1/subfolder2/subfolderN
while [[ $f != / ]]; do chmod +rx "$f"; f=$(dirname "$f"); done;

This starts with whatever file/directory you set f too, and works on every parent directory, until it encounters "/" (or whatever you set the string in the condition of the loop to). It does not chmod "/". Make sure both f and the directory in the condition of the loop are absolute paths.

5
  • Nice, I knew I was complicating things needlessly with Perl.
    – terdon
    Sep 14 '13 at 4:02
  • But what if f is a relative path, and I want to stop at what it is relative to instead of /?
    – Tim
    Jun 15 '18 at 13:33
  • @StéphaneChazelas Thanks. If $f is foo/bar, will $f ever change to .? Yes dirname does it. Thanks
    – Tim
    Jun 15 '18 at 13:37
  • 2
    @Tim convert relative path to absolute path before storing in f using command "f=`readlink -f <relative_path>`" Apr 15 '19 at 11:03
  • 1
    Remember to use absolute path. I used short link path and had a lot problems. Finally get it back to normal. Feb 20 '20 at 20:21
6

With csh, tcsh, ksh, zsh, bash, fish or yash -o braceexpand:

sudo chmod +rx /root{,/subfolder1{,/subfolder2{,/subfolderN}}}

With zsh:

f=/root/subfolder1/subfolder2/subfolderN
until [[ $f = / ]] {chmod +rx $f; f=$f:h;}

Or you could define a glob qualifier function like:

explode() {
  reply=()
  until [[ $REPLY = [./] ]] {
    reply+=$REPLY
    REPLY=$REPLY:h
  }
}

To be used for instance as:

$ echo chmod +rx subfolder1/subfolder2/subfolderN(+explode)
chmod +rx subfolder1 subfolder1/subfolder2 subfolder1/subfolder2/subfolderN  

Note that chmod +rx is affected by the umask. If your umask doesn't include 007, it would make the /root directory world-readable and accessible which is a bad idea. /root is typically for the super-user's private things, it's a bad idea to expose it.

3
  • Could you explain what the leading , in {,/subfolder} does?
    – terdon
    Sep 14 '13 at 14:28
  • It creates an alternation where the first string is empty and the second is /subfolder; so /root{,/subfolder} produces /root and /root/subfolder
    – tripleee
    May 25 '18 at 5:15
  • Notably this is not portable to POSIX sh
    – tripleee
    May 25 '18 at 5:15
2

I don't know what you are trying to do, but is better than you don't take the recursive lightly. That said, read the actual answer:

Umm... why not just use recursive.

sudo chmod -R +rx /root

Or if you don't like it, you can give chmod several directories:

sudo chamod +rx /root /root/subfolder1 /root/subfolder1/subfolder2 /root/subfolder1/subfolder2/subfolderN
3
  • 5
    That's not nearly the same operation, though. chmod -R /root changes everything under /root — including regular files and all directories. The question is about changing one chain of directories only. Sep 14 '13 at 4:04
  • @200_success but that's not the only answer ;)
    – Braiam
    Sep 14 '13 at 4:08
  • The question is not about recursion, but how to set permissions on a chain of parent folders to allow selective access to a subfolder. Saying that it's not the only answer is like saying driving a bus through your wall is another way to make a door.
    – jmc
    Nov 13 '18 at 15:13
2

Well, you could do something slightly more complex like:

echo "/root/subfolder1/subfolder2/subfolderN" | 
 perl -anF'/' -e 'while($#F>0){@b=join("/",@F);`chmod +rx @b`; pop @F}' 

To see what this will do, replace the chmod call with print:

$ echo "/root/subfolder1/subfolder2/subfolderN" | 
 perl -alnF'/' -e 'while($#F>0){@b=join("/",@F);print "chmod +rx @b"; pop @F}' 
chmod +rx /root/subfolder1/subfolder2/subfolderN
chmod +rx /root/subfolder1/subfolder2
chmod +rx /root/subfolder1
chmod +rx /root

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.