I was deploying a second copy of an application on a system the other day, for ongoing development purposes, and I kept running into issues that seemed like I must have had some file permissions wrong. The installations are (purposely) not identical, but rather close except for a few extensions in each case.
None of the problems I was having with the development installation were occurring with the (for lack of a better word) production installation of this application, so I under took to compare file and directory permissions through the two directory trees. 344 directories, 3423 files in one case, and 486 directories, 5217 files in the other. Doing this by hand would have been a nightmare, so I got to thinking …
I’ve been using find in various, usually very simple ways for decades now, yet I’ve only ever barely scratched the surface of what it can do. I was pretty sure, though, that find would provide the solution I needed: walk down one directory tree, and for each file and directory you, well, find, look to see if one exists by the same name under a different directory tree that can be considered the “model”. If it does, but ownership and / or permissions are different, adjust the former to match the latter.
The idea seems simple enough, time for a shell script:
#!/bin/sh
# 2024-10-29 Sylvain Robitaille: one-off script to walk down a
# directory tree and mirror file/directory ownership and permission
# from a parallel directory tree.
# ----------
TOPDIR=/path/to/target/directory
PARDIR=/path/to/mirror/directory
for filedir in `cd ${TOPDIR} && find -xdev \\( -type f -o -type d \\)`; do
if [ -e ${PARDIR}/${filedir} ]; then
if [ `stat -c %u ${TOPDIR}/${filedir}` -ne `stat -c %u ${PARDIR}/${filedir}` ]; then
chown `stat -c %u ${PARDIR}/${filedir}` ${TOPDIR}/${filedir}
fi
if [ `stat -c %g ${TOPDIR}/${filedir}` -ne `stat -c %g ${PARDIR}/${filedir}` ]; then
chgrp `stat -c %g ${PARDIR}/${filedir}` ${TOPDIR}/${filedir}
fi
if [ `stat -c %a ${TOPDIR}/${filedir}` -ne `stat -c %a ${PARDIR}/${filedir}` ]; then
chmod `stat -c %a ${PARDIR}/${filedir}` ${TOPDIR}/${filedir}
fi
fi
done
This worked exactly as intended. The ownerships and permissions under the target directory exactly matched those in the mirror directory. In the end, the trouble that I was having was solved with some obscurely documented configuration, and filesystem permissions were not the problem after all, but by being able to be sure that I had ownership and permission matching between the two installations, I successfully eliminated that as my problem, despite what the symptoms were. A little bit of configuration magic, and the development installation of the application functions according to the in-use version. Life goes on.
I fully expect that I’ll add more quick little handy uses of find, as I recall those I’ve used over the years (no-doubt some that I simply don’t even think about), or as I come up with new ones.