6.6 Deleting a File

6.6  Deleting a File

 

Assuming we have write permission to a directory, we can delete a file by using the unlink command. In Unix, we must have write access to a directory to delete a file although write access to the file is not necessary. File permissions are usually not an issue in Windows and the Macintosh operating system prior to OS X.

Below, we write a program that takes a command line argument that it considers to be a list of files. It removes those files that have ~ (the tilde) at the end. One frequently sees such files on Unix machines. In Unix, these are  usually old copies of files that were created as backup by various text editors during the editing process.

 Program 6.8

#!/usr/bin/perl
use strict;

my $file;
my @files = grep /~$/, @ARGV;
foreach $file (@files){
    unlink $file;
}

The unlink command reduces the number of links a file has by 1. For files that have not been linked from elsewhere, the number of links is just one. So, for such files, unlink deletes them.

Assume the program given above is stored in a file cleand1.pl. A possible call to the program is given below.

 

%cleand1.pl *

 

unlink returns the number of files that it has successfully unlinked. However, in this program, we are not using the returned value for any purpose.

  As a second example, we consider an environment in which we use the text processor called LaTeX or TeX. These word processors create files with .dvi, .log and .aux endings. They may also create other temporary files depending on the task requested. These temporary files are normally not needed after processing and printing the files. The following program deletes all such files from a directory. We can run this program after word processing a document file with LaTeX.

 Program 6.9

#!/usr/bin/perl

use strict;
my ($file, @extensions);
@extensions = qw(dvi log aux);

my @files = map {my $extension = $_;
                 grep /\.$extension/, @ARGV;
                 }
                 @extensions;
print "files = @files\n";

foreach $file (@files){
    unlink $file;
}

This program has a set of extensions for files it wants to remove. The extensions are stored in the list @extensions. In this case, the extensions are dvi, log, and aux. Next, the program has a block of code that is mapped over the list @extensions. This block of code obtains all files with the specified extensions from the list of files in @ARGV and places them in @files. The program, then, goes over all the found files and unlinks them.

If the program is stored in the file rmTeXfiles.pl, a sample call to the program is given below.

 

%rmTeXfiles.pl *

 

This call removes all files in the current directory with the given extensions.

We may want the program to report to us if it cannot delete or unlink any file from the list of files to remove. We can do that by using the warn function along with the call to unlink.

A version of the previous program that uses warn is given below.

 Program 6.10

#!/usr/bin/perl

use strict;
my ($file, @extensions);
@extensions = qw(dvi log aux);

my @files = map {my $extension = $_;
                 grep /\.$extension/, @ARGV;
                 }
                 @extensions;
print "files = @files\n";

foreach $file (@files){
    if (!(unlink $file)){
         warn "Cannot delete file $file: $!";
    }
}

The unlink command returns true if it is able to remove the file. Otherwise, it returns false. When unlink returns false in the program given above, the program calls warn to print a warning message. The unlink command sets the special variable $! if there is an error.  In string context, $! is a descriptive error message saying what the problem is.

In Unix systems, it is possible to remove files even if the user does not have read or write permission or both for the file. The ability to remove a file is determined by if the user has permission to write to the directory containing the file. Therefore, if the directory containing the files does not have write permission, the program will print an error message saying something like the following. 

 

Cannot delete file a.aux: Permission denied at rmTeXfiles1.pl line 15.

 

Here, rmTeXfiles1.pl is the name of the program that we are running.

The warn function is more expressive than a print statement. The warn and the unlink functions can be used as show in either of the following statements.

 

unlink $file || warn "Cannot delete file $file:",   $!;

unlink $file or  warn "Cannot delete file $file:",   $!;

 

  If unlink is able to delete the file, it returns true. In such a case, the warn command is not run. However, if unlink fails and returns false, || (or, or) allows the warn command to be executed. Both || and or are short-circuit operators.
or is easier to read and has lower precedence than ||.