Problem
Synology NASs have a Task Scheduler that allows you to schedule deletion of files over X days old from recycle bins. This feature isn’t working for me–running the task results in no files being deleted. The task works if I schedule a full deletion of the recycle bin, but I’d prefer to only delete a file if it sits in the bin for more than X days. As such, I’ve created this user script to do so. I want to make sure that it deletes exactly as I want.
- Only entries within the recycle bin of the specific shared folder
/volume1/share1/#recycle/
- Only files that are over 60 days old
- Not the recycle bin folder itself
- Delete empty folders
Script:
deletepath="/volume1/share1/#recycle/"
logpath="/volume1/share2/SynoScripts/logs/deleteOlderThanXDays.txt"
errorpath="/volume1/share2/SynoScripts/errors/deleteOlderThanXDays.txt"
now=`date "+%Y-%m-%d %H:%M:%S"`
echo "" >> $logpath
echo $now >> $logpath
echo "" >> $errorpath
echo $now >> $errorpath
# Delete files
/usr/bin/find $deletepath -type f -mtime +60 -exec rm -v {} ; >>$logpath 2>>$errorpath
# Delete empty folders
/usr/bin/find $deletepath -mindepth 1 -type d -empty -exec rmdir {} ; >>$logpath 2>>$errorpath
Does this script appear to satisfy my requirements?
Solution
If this is intended to be run as a command, I recommend you add a suitable shebang line. Although the question is tagged bash, there’s nothing here that isn’t portable POSIX shell, so I recommend
#!/bin/sh
Is it intentional that the paths all share a common initial prefix /volume1
and that the log and error paths share a longer common prefix? If so, encode that for easier re-use:
volume=/volume1
scriptdir=$volume/share2/SynoScripts
logpath=$scriptdir/logs/deleteOlderThanXDays.txt
errorpath=$scriptdir/errors/deleteOlderThanXDays.txt
Personally, I’d call those last two logfile
and errorfile
for clarity.
There’s no need to quote the values in these assignments, but the values should be quoted when used later, so that we don’t break the script when they change to include spaces or other significant characters.
Instead of multiple echo
commands, consider using a single date
with tee
:
date '+%n%Y-%m-%d %T' | tee -a "$logpath" >>"$errorpath"
After that, we can simply redirect all output and errors:
exec >>"$logpath" 2>>"$errorpath"
When using find
, prefer to group many arguments into a few commands, using +
instead of ;
:
find "$deletepath" ! -type d -mtime +60 -exec rm -v '{}' +
find "$deletepath" -mindepth 1 -type d -empty -exec rmdir -v '{}' +
I assume you meant to use -v
consistently for both commands here.
Modified version
#!/bin/sh
volume=/volume1
scriptdir="$volume/share2/SynoScripts"
deletepath="$volume/share1/#recycle"
logpath="$scriptdir/logs/deleteOlderThanXDays.txt"
errorpath="$scriptdir/errors/deleteOlderThanXDays.txt"
# redirect all output and errors
exec >>"$logpath" 2>>"$errorpath"
# log the start time to both logs
date '+%n%Y-%m-%d %T' | tee -a "$errorpath"
# delete old non-directory files (including devices, sockets, etc)
find "$deletepath" ! -type d -mtime +60 -exec rm -v '{}' +
# delete empty directories, regardless of age
find "$deletepath" -mindepth 1 -type d -empty -exec rmdir -v '{}' +
I think the modified date doesn’t change when the file is moved to #Recycle area, so if the file is already older than 60 days, it will deleted the next time the script runs.
I have observed that the ‘change’ date gets reset when moved to a new directory. Do a ‘stat’ or ‘ls -lc’ of the file before and after moving to different directory and you should see the ‘change’ date reset to current time, while the ‘modified’ date does not change.
I haven’t had time to figure out how to modify the script to use ‘change’ time instead of ‘modfied’ time, but I bet some clever person could code that. Using the ‘change’ date should give you the full 60 days to recover the file.
— update 2020.June.3 —
Looks as though the recent update to DSM, 6.2.3-25426, may have fixed Synology’s method for purging the #recycle area based on how many days have passed since items were moved to the #recycle area.
I had been tinkering with a find command for searching for aged files & folders but not deleting them, only to find that after the update, almost all the aged files, over 60 days, got purged and a bunch of my free disk space was reclaimed.
Anyway .. the core method that seemed to be finding the 60 day aged files in the #recycle bin, though I had not tested with ‘-delete’
find /volume1/Data/#recycle -depth -mindepth 1 -ctime +60 -type f -print -delete
find /volume1/Data/#recycle -depth -mindepth 1 -type d -empty -print -delete