Reputation: 373
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'
Upvotes: 1
Views: 94
Reputation: 289555
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)
Upvotes: 4