skulker — Remove old files from a directory

Format

skulker [–iw][–r|–R] [–l logfile ] directory days_old

Description

skulker finds files that are candidates for deletion in directory, based on comparing the file's access time to the age specified by days_old.

When you call skulker without any options, the files that are candidates for deletion are regular files found using the primaries as shown in the following find command line:
find directory -type f -atime +days_old -level 0 ! -name "*'*" ! -name "*
*" -print
The preceding find command has a deliberate newline inserted as part of the second -name request.

For example, specifying 5 for days_old causes the find command to find files that are equal to or older than five 24-hour intervals earlier than now.

Restriction: This script ignores path names that contain single quotes or newlines when determining the list of objects that are candidates for deletion.

The skulker script (which is a z/OS shell script in /samples) should be copied and can be modified to suit your particular needs. Possible locations for placing the script include /bin or /usr/sbin, especially if skulker is to be run from a UID(0) program. If skulker is to be run by users, /usr/bin is another possibility, but check that the sticky bit is on in the directory. If the script is called from a privileged user (a superuser, a user with a UID of 0, or a user running with the RACF® trusted or privileged attribute), it is important to protect the script from any modifications by a non-privileged user.

The code page in which a shell script is encoded must match the code page of the locale in which it is run. For a shell script to be shared by multiple users, they must all be in a locale that uses the same code page as the code page in which the shell script is encoded. If you have different users operating in various locales, you need multiple copies of the skulker shell script, one for each different locale code page. You can use the iconv command to convert the skulker shell script from one code page to another.

Options

–i
Displays the files that are candidates for deletion, and prompts the user to stop or continue with file removal. Do not use this option if you are invoking skulker from a cron job. If skulker is invoked with –i from a cron job, no files will be deleted. A message will be mailed to the caller, showing the skulker output that includes the message “Request canceled".
–l logfile
Specifies a logfile to store a list of files that have been deleted, are candidates for deletion, or for which warnings have been mailed; and any errors that might have occurred.
–r
Moves recursively through subdirectories, finding non-directory files that are equal to or older than the specified number of days. The files that are candidates for deletion are found using the primaries as shown in the following find command line:
find directory -atime +days_old ! -type d ! -name "*'*" ! -name "*
*" -print
The find command in the preceding example has a deliberate newline inserted as part of the second -name request.

The -r option is mutually exclusive with the -R option.

–R
Moves recursively through subdirectories, finding both non-directory files and subdirectories that are equal to or older than the specified number of days. Any subdirectories that are found as candidates for deletion are only deleted if they are empty after all their contents (files, subdirectories and files in subdirectories) that are candidates for deletion have been deleted.
The files that are candidates for deletion are found using the primaries as shown in the following find command line:
find directory -atime +days_old ! -name directory ! -name "*'*" ! -name "*
*" -print
The ! -name directory primary prevents skulker from deleting the actual directory that was entered as a start point (for example, /tmp).

The find command in the preceding example has a deliberate newline inserted as part of the third -name request.

The -R option is mutually exclusive with the -r option.

–w
Does not remove files, but sends a warning to the owner of each old file (using mailx) that the file is a candidate for deletion.
days_old
Specifies the age of the files you want to remove. For example, if you specify 100 for days_old, all files that were last accessed 100 or more days ago are marked as candidates for deletion.
directory
Specifies the directory in which to look for files.

By default, files are removed from the specified directory based on access time and their status as regular files, and are removed only from the directory specified (not from any subdirectories).

Examples

  1. To remove all regular files from /tmp that were last accessed 100 or more days ago:
    skulker /tmp/ 100
    The trailing slash in /tmp/ is necessary if /tmp is a symbolic link and you want to list or remove files from the directory the link points to, rather than the symbolic link itself. If /tmp (or the directory specified) is not a symbolic link, the trailing slash has no effect.
  2. To remove all regular files from /tmp that were last accessed 11 or more days ago:
     > ls -lL /tmp
     total 48
     -rw-------   1 BILLYJC  SHUT           0 Nov 10 06:00 10.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 11 06:00 11.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 12 06:00 12.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 13 06:00 13.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 14 06:00 14.txt
     -rw-------   1 SUPERID  SHUT           0 Nov 15 06:00 15.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 16 06:00 16.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 17 06:00 17.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 18 06:00 18.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 19 06:00 19.txt
     > date
     Mon Nov 29 11:17:20 EST 1999
     > skulker -i /tmp/ 11
     -rw-------   1 BILLYJC  SHUT           0 Nov 10 06:00 10.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 11 06:00 11.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 12 06:00 12.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 13 06:00 13.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 14 06:00 14.txt
     -rw-------   1 SUPERID  SHUT           0 Nov 15 06:00 15.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 16 06:00 16.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 17 06:00 17.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 18 06:00 18.txt
     Do you really want to delete these files?  If yes, answer [y|Y].
     Any other response cancels your request.
     y
     Deleting files...
     > ls -lL /tmp
     total 48
     -rw-------   1 SUPERID  SHUT           0 Nov 15 06:00 15.txt
     -rw-------   1 BILLYJC  SHUT           0 Nov 19 06:00 19.txt
     >
    Note that non-superuser BILLYJC (who issued the skulker command) was not able to delete the superuser's (SUPERID) file (15.txt), even though the find command issued from skulker returned 15.txt as a file name to delete.
  3. The skulker script can be run from a cron job. To use the cron daemon to run the skulker script at 3:15 a.m. every Monday through Friday:
     > crontab
     15 3 * * 1-5 /etc/skulker -l /usr/spool/cron/skulker.log /tmp/ 100
     <control-D>
     >                                                                   
    This example removes all regular files from /tmp that were last accessed 100 or more days ago. By default, cron sends the stdout and stderr of the command in a mail message to the user who submitted the cron job.
  4. To remove all files from /tmp, including subdirectories, that were last accessed 30 or more days ago:
    skulker -R /tmp/ 30

Exit values

0
Successful completion
1
Either skulker did not find any files that are candidates for deletion, or an error occurred.
2
There was a usage error.

Usage notes

skulker only uses the objects access time to determine which objects are candidates for deletion. If you want to use other criteria such as the modify time or the change time, you can modify your own version of skulker to include that criteria. For instance, to modify your version to include the modify time (which, for example, is updated when the object is written to), add the primary
-mtime +days_old 
to the find requests within skulker. To include the change time, add the primary
-ctime +days_old
to the find requests within skulker.

Messages

Possible messages include:
directory is not a directory
The object specified for directory is not a directory object.
find command returned non-zero exit status: return code
The find command returned a non-zero exit status: return code.
Error occurred during remove of file. Return code=return code.
The rm or rmdir command failed with return code while attempting to delete file.
file is in use, not removed.
Some other process was using this file. file cannot be removed.