Search code examples
linuxbashunixserverrm

Unable to Delete Directories Older Than Three Days


I need to delete all sub-directories that are older than three days. The below code should work but it isn't...

for i in `find ~/web/smsng/ -maxdepth 1 -type d -mtime +3 -print`; do echo -e "Deleting directory $i";rm -rf $i; done

Full ls-l listing of directory:

(uiserver):u83749873:~/models/ndfd > ls -l
total 1536
drwx---r-x 2 u83749873 ftpusers 12288 Apr  8 12:41 2016040816
drwx---r-x 2 u83749873 ftpusers 12288 Apr  8 13:41 2016040817
drwx---r-x 2 u83749873 ftpusers 12288 Apr  8 14:40 2016040818
drwx---r-x 2 u83749873 ftpusers 12288 Apr  8 15:41 2016040819
drwx---r-x 2 u83749873 ftpusers 12288 Apr  9 00:41 2016040904
drwx---r-x 2 u83749873 ftpusers 12288 Apr  9 01:41 2016040905
drwx---r-x 2 u83749873 ftpusers 12288 Apr  9 02:41 2016040906
drwx---r-x 2 u83749873 ftpusers 12288 Apr  10 03:41 2016040907
drwx---r-x 2 u83749873 ftpusers 12288 Apr  10 04:41 2016040907
drwx---r-x 2 u83749873 ftpusers 12288 Apr  11 07:41 2016040907

Solution

  • Change -mtime +3 to -mtime +2:

    for i in `find ~/web/smsng/ -maxdepth 1 -type d -mtime +2 -print`; do
        echo -e "Deleting directory $i"
        rm -rf $i
    done
    

    According to the find(1) man page:

    -mtime n

    File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.

    Other improvements

    There are some improvements you could make to your script to improve hardiness with regard to being able to process any possible file name.

    Currently, your script will fail to work if:

    • Any directory has a space, tab, or newline character in it
    • The $i variable starts with a hyphen (-)

    You can fix both these issues if if you write the script like so:

    find ~/web/smsng/ \
        -maxdepth 1 -type d -mtime +2 \
        -exec echo 'Deleting directory {}' \; \
        -exec rm -rf -- {} \;
    

    Because it's never interpreted as an argument list by the shell, split-on-whitespace never happens. Because it's passed to rm with the option-terminating -- the filename can begin with a hyphen and not get interpreted as a flag to rm.