Housekeeping Not Working

Hi,

I have a .ksh script which finds all the directories older than 84 days and tries to housekeep. Below is the command used

find * -depth -type d -ctime +84 -exec rm -rf {} \;

The above command lists all the directories ie child and parent directory in descending order which are more than 84 days old

When the script is executed from unix prompt, it does what it was intended for.

But when the same is executed by calling from another .ksh script on a by a oracle batch scheduler it is deleting only the subfolders and not the parent folder.

Can someone throw some light on this.

Files in subdirectories may be newer than the parent dir, so this sounds insufficient and dangerous. Most go by mtime not ctime.

But, if your situation is that the files and subdirs are laid down just after the directory is created, that is OK. Using -depth seems like a waste, and + from {} is faster. Note that if rm returns not zero, because it cannot remove something due to permissions, find stops.

Does your script have a good #!path-to-shell as line 1, and chmod executable? It may be running under a different shell in the scheduler.

Hi

the subdirectories and parent directory have the same dates

eg.

Directory D1 - D12, F1, F2, F3, F4, F5

D1 Parent Directory
D12 - Sub-Directory
F1, F2.... - Files in Directory D1

When the command find * -depth -type d -ctime +84 -exec rm -rf {} \; is executed only the Directory D12 is deleted.
The files F1, F2..... and Directory D1 is not removed.

The funny part is when i run the command from command line, it removes D1, D12,Fn. But when this is part of the batch script called from oracle Scheduler its not working as intended and deletes only the sub directory D12.

Usually, when batch script runs differently, it is the #! (see man execvp()) or permissions. One slip and it runs in the bourne shell as stdin.

finds first argument usually is the path where to start the search. You have * as first argument so all entries in your current working directory are passed as argument.
If you want your script to start searching in the current directory use the dot or even better use the absolute path where to start (especially when you execute rm on hits).

find . -depth -type d -ctime +84 -exec rm -rf {} \;

or

find /path/to/D1 -depth -type d -ctime +84 -exec rm -rf {} \;

Hi Pickett / Cero,

Thanks for your valuable inputs.

Instead of "-depth" clause, can i use -prune which will just list only the parent directory?

Also could it be due to path issues as the script is working fine when i execute it from command line. But the problem arises only when it is called from oracle batch scheduler. The reason for the above doubt is because the path is different between command line and when called from batch scheduler.

By path do you mean the PATH variable or your current working directory? The variable should not have much effect on the result, but your current working directory for sure has when you do not use an absolute path.
GNU find would do something completely different when using -prune ( = do not descend into directories) instead of -depth ( = process directories content first), so it depends on what you try to archive.

Hi Cero,

Yes, PATH Variable. The PATH has $HOME/bin included which has a value set and this gets appended when i run the script from command line.

But when the script is invoked via a batch procedure there is no value for $HOME and just /bin is getting appended into $PATH variable.

As you have highlighted in your earlier comment i have given the absolute path in my script now. Hopefully this should solve the problem when it runs the next time. finger crossed. Will update you soon.

---------- Post updated at 06:51 AM ---------- Previous update was at 06:49 AM ----------

one clarifitication

the command which i have used above, will first fetch all the directories and then sent as a bulk input to the rm command or the find fetches one row sends to rm, then fetches second row and send to rm.

can you clarify that doubt.

---------- Post updated at 07:06 AM ---------- Previous update was at 06:51 AM ----------

Hi Cero,

thanks for your valuable inputs and time. I have modified the script to include the absolute path as u have mentioned earlier.

Also the command i used "find * -depth -type d -ctime +84 -exec rm -rf {} \;" will first all the directories and sub directories and they are passed as bulk input to the rm command. Please correct if my understanding is wrong.

The reason for the above query is because when the child directory D12 is deleted the timestamp on D1 is changing to sysdate (i persume that the time i see in ls is mtime)

The time you see in "ls -la" is indeed the equivalent of "-mtime".
The time you see in "ls -lac" is the equivalent of "-ctime".

Personally I would not base any processing on the value of "-ctime" found a directory timestamp. It is just the timestamp from when the inode was last changed. It is not unusual for "-ctime" to be more recent than "-mtime" in the same directory entry.
Some backup software changes this timestamp.

In fact the whole idea is dodgy because the "-ctime" stamp on a parent can be older than of the subdirectory ... and you are issuing "rm -r".

Hi Cero,

Thanks for the update once again.

Well i need to find all the directories older than x days and housekeep them. the problem i am facing is, only the child directory D12 is deleted and not the parent directory D1 when i use the command find * -depth -type d -ctime +84 -exec rm -rf {} \; (Both D1 and D12 are created on the same day)

My observation is when the child directory D12 is deleted, the ctime of parent directory D1 changes to sysdate and hence the above command does not list the parent directory as it doesnt satisfy the X days old condition. Am i right in my interpretation.

Yes, you clear files by date and then empty directories.