Developer

Script Teez: Core removal

Core files can sometimes pepper our Linux filesystem completely unbeknownst to us. With the help of Vincent Danen's scripting expertise, you can remove those files simply and efficiently.


Last month we took a look at a script written in Perl that was designed to search for suid programs on the hard drive and report to us those linked against the ncurses library. This month we will take the same kind of approach but for a much more practical use. Ever find those annoying core files on your system? Those core files are the result of misbehaving programs exiting suddenly and leaving behind an informational dump that is only of use to a programmer and not much use to those of us doing everyday computing on the Linux platform. In fact, they are quite annoying and, if left unchecked, can claim a lot of disk space.

This month we use Perl once again to get rid of any core files on the computer in a nice clean fashion with a relatively pleasing interface. We once again make use of the find program, which we use to locate the files.

This script is a little more elaborate and has the feel of a professional Perl program called findcore. The contents of findcore are as follows:
#!/usr/bin/perl
print "Looking for core files...\n";
#find command looks from / for real files (no dirs, symlinks, etc.)
#named core
@core = `find / -type f -name core 2>/dev/null`;
chop (@core);
$num = @core;

if (@core) {
if ($num == 1) {
print "Found $num core file... removing...\n";
} else {
print "Found $num core files... removing...\n";
}
foreach $file (@core) {
# if we have write (-w) permission for file, we can delete it
if (-w $file) {
system("rm -rf $file");
print "Deleted $file.\n";
} else {
print "You do not have permission to delete $file!\n";
}
}
} else {
print "No core files found!\n";
}
exit(0);


This script is relatively simple to write and use. Simply give it execute permissions and run it like this
chmod 755 findcore
./findcore


as any user. This program does some permission checking, so if you run it as a regular user and there is a core file found that can only be deleted by root (or another user), it will tell you.

The first step, as always, is to tell the system where to find the Perl interpreter. In most cases, it should be in /usr/bin/perl. Then, we tell the user what we are doing. Since we're looking for core files, we tell them this with the print function.

The next step is to execute the find command and print the results to an array called core, which is represented by the variable @core. We use a different find command here than we did last month, so let me explain the syntax. First, we search from the root directory, but we only look for files of a specific type; in this case we look for regular files. The reason for this is that we don't want to start deleting directories called core or symbolic links called core. Also, we don't want to delete any block device names, sockets, and so on. Core dumps result in a regular file, so this is the only file type we are interested in. That is what "-type f" stands for. (Read the find man pages to find out how to specify different file types.) Next, we only want files whose names match "core." All other files are of no interest to us at all. Finally, since find will tell us that we don't have permission to search in various directories and print this information to the screen, we redirect the error messages to the bitbucket (/dev/null). We can't redirect everything to /dev/null, otherwise we will always have an empty array. Since we want the normal output that find gives us (the list of files matching our search pattern), we can only redirect STDERR (represented by the number 2) to /dev/null. Thus, our final find command is:
find / -type f -name core 2>/dev/null

Next, we use the chop function on our array to remove all newline characters from any values of our array. We then assign the number of values in the array to the variable $num. If find found two core files, there would be two elements in the array, and the value of $num would be 2. If find doesn't find any core files, the value of $num is 0.

Then, we do a test to see if @core contains any data. We could test to see if $num is equal to 0, but testing @core itself is more efficient. If it does contain data, we perform another test to see if $num is equal to 1. If it is, we print a string that in essence translates to "Found 1 core file...removing..." If $num is not equal to 1 (and because of the previous test against @core, we know it is not 0), we then print "Found x core files...removing..." to the console, where x is the number of elements in the array, representing the number of files found. This gives us a nice and proper way to present what we found. We could have eliminated the test altogether and, if only one core file was found, have the program print "Found 1 core files...removing..." but that doesn't look as nice.

Now, we process the elements in the @core variable using the foreach loop. With the foreach loop, we assign the current element of @core to the variable $file for the duration of the loop. Once again, we perform another test, but this time we check to see whether or not we have write permission to the core file as specified by the $file variable. If we do not have write permission to the file, we can't delete it. We could eliminate this check and have the script print a bunch of "permission denied" errors to the screen, but we've gone to all this trouble to keep the interface clean, so we might as well continue with the trend.

In this case, we use the "-w" test, which is native to Perl, to see whether we can write to the file. If we can, we execute a system call to forcibly remove the file and then print "Deleted [filename]" to the screen. If we do not have write permission, we don't try to remove the file and simply print "You do not have permission to delete [filename]!" to the console.

The foreach loop will go through each element of the @core array, so it will process every core file that find reported. Once this is done, we exit with an exit value of 0, which means the program exited successfully.

Finally, if @core is empty, we print the string "No core files found!" to the console and also exit with an exit value of 0.

All about presentation
This script could have easily been a one-line BASH script if we didn't care about presentation. We do, however, care about presentation, and all we want to see on the screen is the important data. A long display of “permission denied” messages are of absolutely no interest to us, so we took a little bit of time to write a nice Perl wrapper around two basic commands: find and rm. The result is a nice professional-looking output from a relatively basic Perl program.

Once again, we see that Perl is a versatile tool and exceptionally useful for basic system administration. Those who think that Perl is only good for CGI scripts really don't understand how flexible the language can be for basic everyday use.

Conclusion
If you look at the last Script Teez, you will realize that the basic fundamentals are the same. Both scripts have the same basic function: finding certain files. The actions that are run on the returned files are the differing factor here. Last month we simply reported on the found files, while this month we remove the found files. The uses for this kind of script are infinite. You can modify the script to go through your system and remove a certain type of file, whether you want to remove a bunch of text files matching a certain file pattern or you want to remove all backup files. It's also simple enough that someone without a great understanding of Perl can make use of it for a variety of situations.
The authors and editors have taken care in preparation of the content contained herein but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.

About Vincent Danen

Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.

Editor's Picks