Notes: Perl Lab 10

File and Directory Manipulation

  1. opendir/closedir
  2. readdir
  3. chdir
  4. unlink
  5. rename
  6. stat

  1. opendir/closedir

    In order to list the contents of a directory the opendir function is used. opendir creates a "directory handle" that can be used to read the contents of the directory in the same way that a file handle is used to read the contents of a file.
    opendir(DIR, '/some/directory/path');
    In the code example above opendir is being used to open the directory specified by the path '/somedirectory/path'. To access the contents of the directory, the dirhandle, "DIR" will be used. To close the dirhandle, the function closedir is used. The syntax is similar to the close function used for closing a file handle. Below is an example closing the "DIR" directory handle.
    closedir(DIR);
    opendir and closedir only manage the opening and closing of the dirhandle. To list and work with the contents of the directory we'll need to use the readdir function.

  2. readdir

    readdir is used to return the next directory entry from the directory specified by the dirhandle. For the dirhandle, "DIR", created above, we can read an entry with the readdir function as follows.
    readdir(DIR);
    An example of using opendir, readdir and closedir in a complete script: Example lab10_0.pl
     
    #!/usr/bin/perl -w
    
    # Name: Mark Tucker
    # Assignment: Lab10 Example 00
    # Description: An example of opening and reading the contents of a directory
    #==========================================================================
    
    # set paths
    $thedir = '/usr/doc';
    
    # open the directory
    if( -d $thedir) {
        opendir(DOC, $thedir) || die "cannot open directory $thedir $!";
    }else{
        print "Directory, $thedir, does not exist.  Exiting...\n";
        exit;
    }
    
    # iterate through the directory entries
    while($item = readdir(DOC)) {
        my $fullpath = $thedir.'/'.$item;
        # find subdirs that begin with the letter "z"
        if(($item =~ /^z/) && ( -d $fullpath )) {
            print "$item is a directory\n";
        }
    }
    
    # close the directory handle
    closedir(DOC);
    
    exit;
    # DONE
    
    

    When executed, the script above produces the following output:
     
    [mark@platypus PERL] ./lab10_0.pl  
    zip-2.3 is a directory
    ziptool-1.3 is a directory
    zisofs-tools-1.0.4 is a directory
    zsh-4.0.6 is a directory
    zlib-1.1.4 is a directory
    [mark@platypus PERL] 
    

  3. chdir

    Any running perl script has a "working directory" value, generally the directory where the Unix shell executed the script. The chdir function changes this working directory to the path specified as it's argument.

    Example lab10_1.pl
     
    #!/usr/bin/perl -w
    
    # Name: Mark Tucker
    # Assignment: Lab10 Example 01
    # Description: An example of opening and reading the contents of a directory
    #==========================================================================
    
    # set paths
    $thedir = '/usr/doc';
    
    # change to $thedir
    chdir($thedir);
    
    # open the current directory and read the entries into an array
    opendir(DIR, ".") || die "cannot open dir . $!";
    @files = readdir(DIR);
    closedir(DIR);
    
    # iterate through all the names in the array and print selected entries
    foreach $i (@files) {
        print "$i\n" if($i =~ /ux/);
    }
    
    # change directory to the user's $HOME
    chdir($ENV{HOME});
    
    exit;
    # DONE
    
    

    When executed, the script above produces the following output:
     
    [mark@platypus PERL] ./lab10_1.pl  
    syslinux-2.01
    util-linux-2.11z
    Linux-FAQs
    Linux-HOWTOs
    Linux-mini-HOWTOs
    [mark@platypus PERL] 
    

  4. unlink

    To remove (delete) a file the unlink function is used. unlink can take a list of files to remove. Filenames must be specified using their absolute path unless the perl script has it's working directory set to the directory where the files are located.
    unlink('/some/path/filename.txt');
    or mulitple files:
    unlink('/some/file.dat', $file_var, $another_file);

    Example lab10_2.pl
     
    #!/usr/bin/perl -w
    
    # Name: Mark Tucker
    # Assignment: Lab10 Example 02
    # Description: An example of removing files
    #==========================================================================
    
    # change directory to the user's home
    chdir($ENV{HOME});
    
    # open the directory.  Note that "." designates the current directory.
    opendir(HM, '.') || die "cannot open dir . $!";
    
    # read the contents of the directory
    while($item = readdir(HM)) {
        
        # delete any files that end with ".out"
        if((-f $item) && ($item =~ /\.out$/)) {
            # ask the user to delete
            print "We are about to delete the file $item, proceed? [Y/N]\n";
            chomp($ans = <STDIN>);
            if($ans =~ /^[yY]/) {
                # delete the file. No path specifed since we have changed directory
                # to the current dir where the file is stored.
                unlink($item);
            }
        }
    }
    
    exit;
    # DONE
    
    

    When executed, the script above produces the following output:
     
    [mark@platypus PERL] ./lab10_2.pl  
    We are about to delete the file dump.out, proceed? [Y/N]
    y
    We are about to delete the file file.out, proceed? [Y/N]
    y
    We are about to delete the file df.out, proceed? [Y/N]
    y
    We are about to delete the file who.out, proceed? [Y/N]
    y
    We are about to delete the file new.out, proceed? [Y/N]
    y
    We are about to delete the file env.out, proceed? [Y/N]
    y
    We are about to delete the file junk.out, proceed? [Y/N]
    y
    [mark@platypus PERL] 
    

  5. rename

    To rename a file within perl the rename function is used.
    rename('/dir/file/oldname.txt', '/dir/file/newname.txt');
    Again, unless the working directory is set (using chdir()) to the directory containing the file to be renamed the absolute path to the file must be specified.

  6. stat

    The stat function in perl returns a list of information about the specified file or file handle.

          0 dev      device number of filesystem
          1 ino      inode number
          2 mode     file mode  (type and permissions)
          3 nlink    number of (hard) links to the file
          4 uid      numeric user ID of file's owner
          5 gid      numeric group ID of file's owner
          6 rdev     the device identifier (special files only)
          7 size     total size of file, in bytes
          8 atime    last access time in seconds since the epoch
          9 mtime    last modify time in seconds since the epoch
          10 ctime    inode change time in seconds since the epoch (*)
          11 blksize  preferred block size for file system I/O
          12 blocks   actual number of blocks allocated
    

    Example lab10_3.pl
     
    #!/usr/bin/perl -w
    
    # Name: Mark Tucker
    # Assignment: Lab10 Example 03
    # Description: An example of getting file information with stat()
    #==========================================================================
    
    # set file
    $testfile = $ENV{HOME}.'/.emacs';
    
    @file_info = stat($testfile);
    
    $fsdev = $file_info[0]; # device number of filesystem
    $inode = $file_info[1]; # inode number
    $mode  = $file_info[2]; # file mode  (type and permissions)
    $nlink = $file_info[3]; # number of (hard) links to the file
    $uid   = $file_info[4]; # numeric user ID of file's owner
    $gid   = $file_info[5]; # numeric group ID of file's owner
    $rdev  = $file_info[6]; # the device identifier (special files only)
    $size  = $file_info[7]; # total size of file, in bytes
    $atime = $file_info[8]; # last access time in seconds since the epoch (1970)
    $mtime = $file_info[9]; # last modify time in seconds since the epoch (1970)
    $ctime = $file_info[10]; # inode change time in seconds since the epoch (*)
    $blksize = $file_info[11]; # preferred block size for file system I/O
    $blocks = $file_info[12]; # actual number of blocks allocated
    
    # print the file size
    print "File size for $testfile is $size bytes\n";
    
    # another method for showing the file size
    print "File size for $testfile is ". (stat($testfile))[7] ."\n";
    
    exit;
    # DONE
    
    

    When executed, the script above produces the following output:
     
    [mark@platypus PERL] ./lab10_3.pl  
    File size for /mnt/homes/tuckerm/.emacs is 3144 bytes
    File size is 3144
    [mark@platypus PERL]
    


last updated: 18 Mar 2012 13:00