I'm trying to write a shell script to preserve and rewrite all permissions/groups in a large directory with several subdirectories in the event they get changed or are not properly created or if mirroring the users/permissions for this directory on a different machine.

Something like:

chown adam:brown /var/blarg
chmod 770 /var/blarg
chown adam:brown /var/blarg/toast.file
chmod 777 /var/blarg/toast.file


Doing this by hand will take a long time. I was wondering is there an existing command/script to accomplish this task?

  • Why not chown -R adam:brown /var/blarg and chmod -R 770 /var/blarg? If not, can you please clarify where these files are. A single file isn't much to find a pattern. – Patrick May 8 '14 at 14:18
  • Have a take look at monit. mmonit.com/monit – Rahul Patil May 8 '14 at 14:19
  • @Patrick It's a large directory with many sub directories of varying depth – blarg May 8 '14 at 14:27
  • 2
    Play with something like find . -printf 'chown %u:%g %p\n'. man find will show how to print out the other properties you are interested in too... – user62916 May 8 '14 at 14:30
  • @yeti Thanks! That seems to be what I was looking for. For the permissions I used find . -printf 'chmod %m %p\n' Why don't your add this as an answer to this question so I can accept it? – blarg May 8 '14 at 14:47

Along the lines of @yeti's comment, I thought about this a while back, and seem to remember coming to the conclusion that something like

find /path/to/dir -printf '%m\t%u\t%g\t%p\0' > filelist

and then

while read -rd $'\0' perms user group file; do 
  if [ -e "$file" ]; then
    chown "$user:$group" "$file"
    chmod "$perms" "$file"
    echo "warning: $file not found"
done < filelist

would work. Putting the filename last in the output and using read and null terminators instead of newlines should make it safe even for filenames with spaces and other special characters. Depending where you want to run the second command from, it might be more convenient to use the filename with the leading /path/to/dir component from the find command removed i.e. %P in place of %p.

  • That's exactly what I want! Thanks @steeldriver – Marslo Jan 16 '17 at 14:47

As yeti suggested in the comments, I used the find command to find all files and directories within the directory and output their permissions/owners into a chown or chmod command. I added the verbose -v option so when running the resulting shell scripts you can see the success/errors of the commands:

find /var/blarg -printf 'chown -v %u:%g %p\n' > chowns.sh
find /var/blarg -printf 'chmod -v %m %p\n' > chmods.sh

Now just make the resulting .sh files executable:

chmod +x chowns.sh; chmod +x chmods.sh

Then run them and output the verbose feedback to a txt file:

./chmods > chmods_results.txt


  • You just reinvented chown -R and chmod -R. Albeit worse now, as if any of your filenames have spaces or other special characters, it'll break. – Patrick May 8 '14 at 16:15
  • How? It's much more intricate than chown/chmod -R. Those commands can only set the whole folder recursively to one user/set of permissions. – blarg May 12 '14 at 15:20
  • Which is exactly what your custom solution just did... – Patrick May 12 '14 at 15:26
  • @Patrick. Try reading through it. My solution has read all current permissions for each individual directory/file using find and saved them a separate command in a shell script. E.G. a directory contains 3 files each owned by a separate user. Your solution can only assign them to one user. Mine can assign them to all three seperately. The idea is to take an existing directory on one machine and mirror the permissions on another, or repair them if changed. – blarg May 12 '14 at 15:36
  • ahh, you want to preserve the current permissions so you can reapply them in the future. Ok, that makes sense then. Would you mind clarifying that in your question? The only thing that even hints at it is the title. – Patrick May 12 '14 at 15:40

You mention events, and if you have really many files it makes sense to watch for these. You may want to have a look at inotifywatch, which "listens for filesystem events" , e.g. change of file permissions. On debian based OS it resides in package inotify-tools .

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.