Recipe 9.8. Removing a Directory and Its Contents
Author: Tom Christiansen & Nathan Torkington
Date: 1999-07-02T01:39:19Z

#

| Chapter 9 Directories |

## 9.8. Removing a Directory and Its Contents

### Problem

You want to remove a directory tree recursively without using `rm` `-r`.

### Solution

Use the `finddepth` function from File::Find, shown in Example 9.3.

#### Example 9.3: rmtree1

    #!/usr/bin/perl
    # rmtree1 - remove whole directory trees like rm -r
    use File::Find qw(finddepth);
    die "usage: $0 dir ..\n" unless @ARGV;
    *name = *File::Find::name;
    finddepth \&zap, @ARGV;
    sub zap {
        if (!-l && -d _) {
            print "rmdir $name\n";
            rmdir($name)  or warn "couldn't rmdir $name: $!";
        } else {
            print "unlink $name";
            unlink($name) or warn "couldn't unlink $name: $!";
        }
    }

Or use `rmtree` from File::Path, as shown in Example 9.4.

#### Example 9.4: rmtree2

    #!/usr/bin/perl
    # rmtree2 - remove whole directory trees like rm -r
    use File::Path;
    die "usage: $0 dir ..\n" unless @ARGV;
        foreach $dir (@ARGV) {
        rmtree($dir);
    }

> WARNING: These programs remove an entire directory tree. Use with extreme caution!

### Discussion

The File::Find module exports both a `find` function, which traverses a tree in the (essentially random) order the files occur in the directory, as well as a `finddepth` function, which is guaranteed to visit all the files underneath a directory before visiting the directory itself. This is exactly what we need to remove a directory and its contents.

We have to use two different functions, `rmdir` and `unlink`. The `unlink` function deletes only files, and `rmdir` only deletes empty directories. We need to use `finddepth` to make sure that we've first removed the directory's contents before we `rmdir` the directory itself.

Check first that the file isn't a symbolic link before determining if it's a directory. `-d` returns true for both a directory and a symbol link to a directory. `stat`, `lstat`, and the file test operators like `-d` all use the operating system call stat (2), which returns all the information kept about a file in an inode. These functions and operators retain that information and let you do more tests on the same file with the special underscore ( `_` ) filehandle. This avoids redundant system calls that would return the same information, slowly.

### See Also

The `unlink` , `rmdir`, `lstat`, and `stat` functions in perlfunc (1) and in Chapter 3 of Programming Perl; the documentation for the standard File::Find module; your system's rm (1) and stat (2) manpages; the `-`X section of perlfunc (1), and the "Named Unary and File Test Operators" section of Chapter 2 of Programming Perl

9.7. Processing All Files in a Directory Recursively |  | 9.9. Renaming Files