1

How can I recursive change the permissions of files/directories to become group permissions the same as owner permissions?

e.g. Before:

640 x.txt
744 y
400 y/z.txt

After:

660 x.txt
774 y
440 y/z.txt

Thanks to fedorqui got created this as answer:

find . -name '*' -print0 | xargs -0 bash -c 'for file; do 
perm=$(stat -c '%a' "$file")
new_perm=$(sed -r "s/^(.)./\1\1/" <<< "$perm")
chmod "$new_perm" "$file";
done'
fedorqui
  • 275,237
  • 103
  • 548
  • 598
wdk
  • 373
  • 2
  • 8
  • If you always want to keep the user and group permissions the same, a helpful start is altering your umask: `umask 002` – glenn jackman Nov 30 '15 at 15:15

1 Answers1

4

Using stat you can get the permissions of a file.

For example:

$ touch a
$ stat -c '%a' a
644

Then, if we catch this value, we can use sed to make the 2nd field have the same value as the 1st:

$ sed -r "s/^(.)./\1\1/" <<< "644"
664

And then we are ready to say

chmod 664 file

Now that we have all the pieces, see how can we glue them together. The idea is to catch the first character of the stat output to generate the new value:

perm=$(stat -c '%a' file)
new_perm=$(sed -r "s/^(.)./\1\1/" <<< "$perm")
chmod "$new_perm" file

Then, it is a matter of looping through the files and doing this:

for file in pattern/*; do
   perm=$(stat -c '%a' "$file")
   new_perm=$(sed -r "s/^(.)./\1\1/" <<< "$perm")
   chmod "$new_perm" "$file"
 done

If you want this to be fed by a find result as you indicate in comments and your updated question, you can use a process substitution:

while IFS= read -r file; do
   perm=$(stat -c '%a' "$file")
   new_perm=$(sed -r "s/^(.)./\1\1/" <<< "$perm")
   chmod "$new_perm" "$file";
done < <(find . -name '*' -print0)
Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Thanks, only missing part is recursivity :-) – wdk Nov 30 '15 at 13:59
  • 1
    @wdk there is a beautiful `for` loop that can do this if you are in two levels. Otherwise, and if this contains way more levels, you can use `find` through a process substitution. – fedorqui Nov 30 '15 at 14:01
  • @wdk updated with a `find` approach, since the way you use it in the updated question is a bit overkilling. – fedorqui Nov 30 '15 at 14:29