I have a series of folders, subfolders and files like this :
year_folder
month1_folder
day1_folder
filea, fileb
day2_folder
filea
month2_folder
I want to delete the folders and files older than X days. I have tried
find /c/Documents/year_folder -mtime +5 | xargs rm -rf
This command line works perfectly on my test folders (locally on my computer). But when I run the script on synology, somehow it deletes the whole year_folder.
Unfortunately I do not know how to test my script on the server of synology to understand what I am doing wrong.
Split this into two pieces:
Delete files (only!) older than five days
# for GNU find; see below for POSIX
find "$root" -type f -mtime +5 -delete
Delete empty directories
# for GNU find; see below for POSIX
find "$root" -depth -type d -empty -delete
When you use rm -rf
, you're deleting the entire directory when the directory itself hasn't been updated in five days. However, if you create or modify a/b/c
, that doesn't update the modification time of a
(or, in the case of modifications that don't require the directory itself to be updated, not even that of a/b
) -- thus, your "modification time older than five days" rule is destructive when you apply it recursively.
The only caveat to the above is that it may not delete multiple layers of empty directories at a run -- that is, if a/b/c
is empty, and a/b
is empty other than c
, then only c
may be deleted on the first run, and it may require another invocation before a/b
is removed as well.
POSIX find
doesn't support -delete
. Thus, the first command becomes:
find "$root" -type f -mtime +5 -exec rm -rf -- {} +
Similarly, it doesn't support -empty
. Because rmdir
will fail when passed a non-empty directory, however, it's easy enough to just let those instances referring to non-empty directories fail:
find "$root" -depth -type d -exec rmdir -- {} +
If you aren't comfortable doing that, then things get stickier. An implementation that uses a shell to test whether each directory is empty may look like:
find "$root" -depth -type d -exec sh -c '
rmdir_if_empty() {
dir=$1
set -- "$dir"/* # replace argument list w/ glob result
[ "$#" -gt 1 ] && return # globbed to multiple results: nonempty
{ [ -e "$1" ] || [ -L "$1" ]; } && return # globbed to one result that exists: nonempty
rmdir -- "$dir" # neither of the above: empty, so delete.
}
for arg; do
rmdir_if_empty "$arg"
done
' _ {} +