4

I need to set the same permissions of owner to group recursively to all elements in a directory.

1
  • Only for rwx? Or also for s? (note that s has a different meaning for user/group and regular/directory files). Mar 17, 2015 at 11:41

3 Answers 3

3

There's a fairly simple answer (although I don't know for sure whether it works on all versions of *nix); simply do

chmod g=u *

i.e., set the group permissions equal to the user permissions.

This is documented in chmod(1):

The format of a symbolic mode is [ugoa...][[+-=][perms...]...], where perms is either zero or more letters from the set rwxXst, or a single letter from the set ugo.  …

                ︙

The letters rwxXst select ….  Instead of one or more of these letters, you can specify exactly one of the letters ugo: the permissions granted to the user who owns the file (u), the permissions granted to other users who are members of the file’s group (g), and the permissions granted to users that are in neither of the two preceding categories (o).

5
  • on RHEL 6 it's documented in: info coreutils 'Symbolic modes'
    – jxlxkcyx
    Mar 19, 2015 at 14:39
  • This is the solution I was looking for my problem. I want to open r/x permissions of a directory with subfolders but do not want to change everything to +x. I tried to set umask 022 then 'cp -r' but unfortunately the umask is applied complimentary to the original permissions. With this post's solution, i can do 'chmod -R og=u' then 'chmod -R og-w'
    – fchen
    Feb 3, 2022 at 16:04
  • 1
    @fchen: (1) If you want to be cautious, and go step by step, and see what happens, that’s fine.  But you can combine your two commands into one: chmod -R og=u,og-w or even chmod -R og=u-w.  (2) I guess all your files (and directories) are readable to you, and you’re using og=u as a tricky way of copying the r bit down to the “group” and ”other” bitfields.  In that case, you can simply do chmod -R og=rX (with a capital X).  The capital X means set the x bit if at least one other x bit is already set.  … (Cont’d) Feb 5, 2022 at 4:01
  • 1
    (Cont’d) …  On the other hand, if you have files that aren’t readable to you, and you want to change 100 (---x------) into 111 (---x--x--x) and 300 (--wx------) into 311 (--wx--x--x), then your approach is probably as good as you can get. Feb 5, 2022 at 4:01
  • Thanks a lot!!!
    – fchen
    Feb 5, 2022 at 7:40
1

On a (recent for sed's -z) GNU system, you could do something like:

find . ! -type l -printf '%m:%p\0' |
  sed -Ez '/^.?(.)\1.:/d;s/(.)(.)(.):/\1\1\2\x0/' |
  xargs -r0n2 echo chmod

(remove echo when satisfied with the result).

Note that it only addresses the r, w, x bits not the special ones.

If you don't want it recursive:

find . -mindepth 1 -maxdepth 1 ! -type l -printf '%m:%p\0' |
  sed -Ez '/^.?(.)\1.:/d;s/(.)(.)(.):/\1\1\2\x0/' |
  xargs -r0n2 echo chmod
1

Try this:

for file in $(find .); do
   perm=$(stat -c "%a" ${file});
   echo chmod ${perm:0:1}${perm:0:1}${perm:2:1} ${file};
done

Remember to remove echo.

Improved version:

find . -exec sh -c 'for file do
   perm=$(stat -Lc "%a" "$file")
   echo chmod "${perm:0:1}${perm:0:1}${perm:2:1}" "$file"
done' sh {} +

As in Stéphane Chazelas's answer,

  • Use -mindepth 1 to avoid processing ..
  • Use -maxdepth 1 to avoid recursion (entering subdirectories).
  • Use  ! -type l  to avoid processing symbolic links (although this answer will handle symbolic links OK).

Note that this command will not work correctly for files that have any of the high-order mode bits (setuid, setgid, and sticky) set.

You must log in to answer this question.

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