Skip to content

Instantly share code, notes, and snippets.

@hamiltont
Created March 2, 2015 04:43
Show Gist options
  • Save hamiltont/59eae15b5eaed4d7dd5c to your computer and use it in GitHub Desktop.
Save hamiltont/59eae15b5eaed4d7dd5c to your computer and use it in GitHub Desktop.
Rapidly set user/group/permission on a large media directory and avoid disk writes
#!/bin/bash
# Ensures user/group/permissions are set for a large directory of
# media, while avoiding needless writes and caching where possible.
# Still has to read all media from disk, so all HDDs will spin up -
# e.g. run this infrequently. It's basically an insurance policy
# to avoid losing media, without the cost of writing to every
# file on your NAS with a recursive chown
#
# Needs to be run as sudo
#
# I'd recommend calling this from the root crontab (sudo crontab -e)
# using something like this:
#
# /foo/chown_media.sh 2>&1 | /usr/bin/logger -t media_clean
#
MROOT=/media/mymediafolder
MPERM=0775
MUSER=someuser
MGROUP=somegroup
# Set mode correctly
# Caching: see http://unix.stackexchange.com/a/79872/54389
# 1 - Build filename cache
# 2 - Build inode cache
# 3 - Update inodes (assume user/group are incorrect too)
# Note this uses the GNU extension of "=$MPERM" to remove setuid/gid from
# directories as well
echo "$(date) Starting chmod"
find $MROOT -printf "" &> /dev/null
find $MROOT ! -perm $MPERM -printf "" &> /dev/null
find $MROOT ! -perm $MPERM -exec chmod "=$MPERM" "{}" \; -exec chown $MUSER:$MGROUP "{}" \; -exec echo "chmod: {}" \;
echo "$(date) Finished chmod"
# 1 - Find all files in media root
# 2 - Filter out any currently-open files
# Note that fuser needs to have suid set
# 3 - Filter out files already owned by user
# 4 - chown resulting files
# 5 - Print output
# Don't print fuser warnings about stale file handles
echo "$(date) Starting chown"
find $MROOT ! -user $MUSER ! -exec fuser -s "{}" 2>/dev/null \; -exec chown $MUSER "{}" \; -exec echo "chown: {}" \;
echo "$(date) Finished chown"
echo "$(date) Starting chgrp"
find $MROOT ! -group $MGROUP ! -exec fuser -s "{}" 2>/dev/null \; -exec chgrp $MGROUP "{}" \; -exec echo "chgrp: {}" \;
echo "$(date) Finished chgrp"
@hamiltont
Copy link
Author

Some find explanation: http://serverfault.com/a/672350/91814

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment