How to delete directories and files with xargs?

Hello,

i have an dynamical apache_cache that I need to clean all days (older tant one day) with an unix command :

find /usr/IBM/HTTPServer/apache_cache/ -name '*' -mtime +1 -print0|xargs -0 rm -r --

but it didn't work.

Could you explain me why.

So I will put below all my script :

#!/bin/sh
# About the script
#==============================================================================
# author       : Vision IT Group
# version      : 1.0
# date written : January 2014
# application  : delete -mtime +1 files in the apache_cache
#==============================================================================
#
################################ PATH ###########################################

DATUM1="$(date +%y%m%d.%H%M%S)"
NAME="CacheIHS_Logs"
PATHCACHELOGS="/usr/IBM/HTTPServer/logs/"
LOG_FILE=$PATHCACHELOGS/$NAME.log

################################ CODE ###########################################
#echo "find files to delete in the cache"
#echo "---------------------------------"

find /usr/IBM/HTTPServer/apache_cache/ -name '*' -mtime +1 -print0|xargs -0 rm -r --
if  [ $? -eq 0 ]
then
#Define Logfilename
#------------------
echo "Clear done ..."$DATUM1 >> $LOG_FILE
echo "---------------------------------------" >> $LOG_FILE
else
echo "Error during cleaning log files..." >> $LOG_FILE
fi

Thanks a lot

At the top of my head:

  1. Try just the find command and see if there's any output:
find /usr/IBM/HTTPServer/apache_cache/ -name '*' -mtime +1
  1. Try without -print0 and xargs -0
find /usr/IBM/HTTPServer/apache_cache/ -name '*' -mtime +1 | xargs rm -r
  1. If the interactive mode is aliased to rm , try rm -rf

First, you should explain to us. How did it not work? Show us the error messages. If there weren't any, then at least show us an example of the file hierarchy before running the command, after running the command, and how it should have been after running the command.

You say you "need to clean all days". What is a "day"? A directory? A file? Again, show us a sample of the filesystem hiearchy.

Is everything to be deleted in a single directory, or will find descend into subdirectories? If it will descend, will you be deleting only files, only directories, or both? Depending on the exact nature of the task, a depth-first traversal may be necessary. Again, a better explanation of what's going on is required.

Why are you using -name '*' ? That will always evaluate to true. It's redundant.

Regards,
Alister

If you're already running "find" why not just put the "rm" command there?

find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -exec rm {} \;

Hello,

thanks for your replies. So i need to give more explications sorry.

the command :

find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -exec rm {} \;

is ok i used it before but our Customer said us to use xargs because it's more efficient and quicker.

Yes it is necessary to clean all days so the rule is just to keep one day

The hiearchy is :

drwx------ 3 nobody nobody 4096 May 26 10:53 RWn
drwx------ 3 nobody nobody 4096 Jan 27 19:00 T0t
drwx------ 3 nobody nobody 4096 May 26 13:19 T6Q
drwx------ 3 nobody nobody 4096 Jan 27 19:00 TKg
drwx------ 3 nobody nobody 4096 Jan 27 19:00 UTN

in the directory UTN (per example) are others directories and files that must be clear if there are older than one day. Sometimes the directories could be must spaces.

So if you need more informations, no Problem...

Thanks for your help

Honestly curious.

Do any of these work?

find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -print0 | xargs -0 -n1 rm
find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -print0 | xargs -0 -n1 -I {} rm {}

Change:

find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -exec rm {} \;

to:

find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -exec rm {} +

It is more efficient and quicker than using xargs.

Hello,

thanks

but no the two command didn't work .

The first one give an error : rm: missing operand

The second command didn't nothing but no error

Ok thanks

Thank you for running those.

That's an indication that find is not passing any findings to xargs to execute.

Does find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 alone produce any output?

Hello,

yes i have an output of lot of files.

but i need also to delete dire tories that are older than one day.
That is no optimize the inodes for the disk

Thanks

Your original post uses find -print0 and xargs -0. Is your customer using a GNU userland? If not, those extensions are probably not supported. If they are using a GNU userland and if that's all that needs to be supported, then Don Cragun already gave you the answer.

Why is your customer dictating to you how to solve a problem? I'm inclined to think that they should dismiss you if they know more than you.

Regards,
Alister

The + terminator for find -exec is not a GNU userland extension; it has been required by the standards since 1991.

Note, however, that the command I suggested only removes the regular files; not empty directories. The original code in the OP's script:

find /usr/IBM/HTTPServer/apache_cache/ -name '*' -mtime +1 -print0|xargs -0 rm -r --

which would more efficiently be written as:

find /usr/IBM/HTTPServer/apache_cache/ -mtime +1 -exec rm -r -- {} +

attempts to remove directories and all of their contents and then to remove some of the files in those directories after they have already been removed while removing their parent directory recursively. Furthermore, if a directory hasn't changed in a day, but files in one or more of it subdirectories changed in the last hour, those directories and the new files in them will also be removed.
A safer way to do it would be a two step process: remove the old regular files in the 1st step and then remove old directories in the 2nd step:

find /usr/IBM/HTTPServer/apache_cache/ -type f -mtime +1 -exec rm -- {} +
find /usr/IBM/HTTPServer/apache_cache/ -type d -mtime +1 -exec rmdir -- {} +

Using rmdir instead of rm -r guarantees that you won't remove new files accidentally, but you might get error messages trying to remove directories that aren't empty. If that is a concern, you could redirect stderr from the 2nd find . This method will keep directories that have been emptied by the 1st find around for an extra day (since the directory timestamps will be updated when the regular files in them are removed), but they will be cleaned up one day later if they are then empty.

No, it isn't. If no filenames were passed through the pipe to xargs , xargs should not exec rm . Something else is going on here, but it isn't clear to me what.

Really?

[aia@arrow many]$ ls -l
total 0
[aia@arrow many]$ 
[aia@arrow many]$ find . -name "do_not_exit" -print0 | xargs rm
rm: missing operand
Try 'rm --help' for more information.
[aia@arrow many]$ find . -name "do_not_exit" -print0 | xargs

[aia@arrow many]$ find . -name "do_not_exit" -print0
[aia@arrow many]$ 

Interesting. The standards don't include the -print0 primary for find nor the -0 option for xargs . But, in a directory with the following files:

file
problem
test
tester

The following session using ksh on Mac OS X:

$ find  . -name 'nothing' -print0 |xargs -0 echo xx
$ find  . -name 'nothing' |xargs  echo xx          
$ find  . -name '*r' |xargs  echo xx     
xx ./tester
$ find  . -name '*r' -print0 |xargs -0 echo xx     
xx ./tester
$ 

shows the behavior required by the standards when -print0 and -0 are not used (i.e., no files read by xargs from stdin; no invocations of the specified command). I don't see any reason why the behavior should be different when those options are used; and, at least on Mac OS X, the behavior is the same.