Workshop

The workshop provides quiz questions to help you solidify your understanding of the material covered and exercises to give you experience in using what you've learned. Try and understand the quiz and exercise answers before you go on to tomorrow's lesson.

Quiz

1:What's the difference between a hard link and a symbolic link? What happens if you remove the file that you've linked to with either one?
A1: Hard links provide a way for a single file to have multiple filenames. Removing one instance of the filename—be it the original or the link—leaves all other hard links intact. The file is only actually removed when all the links to it are also removed. Symbolic links also provide a way for a single file to have multiple names, except that the original file is separate from the links. Removing the links has no effect on the file; removing the original file makes any existing links point to nothing.

Note that only Unix systems differentiate between hard and symbolic links, and some Unix systems don't even have symbolic links. Aliases on the Mac or shortcuts on Windows are analogous to symbolic links.

2:What's the difference between `pwd` and cwd()? Why would you want to use one over the other?
A2: The `pwd` command makes use of back quotes and the pwd command in Unix. While some versions of Perl work around this function on other systems, for a more portable version use the Cwd module and the cwd() function. Note: you'll have to import Cwd (use Cwd) before you can use it.
3:What is a file glob? Why are they useful?
A3: A file glob is a way of getting a list of files that match a certain pattern. *.pl, for example, is a glob that returns all the files in a directory with a .pl extension. Globs are useful for grabbing and reading a set of files without having to open the file handle, read the list, and process only those files that match a pattern.
4:What's the difference between a file glob of <*> and the list of files you get with readdir()?
A4: A file glob of <*> returns all the files in a directory, but it does not include hidden files, files that start with a ., or the . and .. directories. Directory handles return all these things.
5:What are the differences between file handles and directory handles?
A5: File handles are used to read and write the contents of files (or to the screen, or to a network connection, and so on). Directory handles are used to read lists of files from directories. Both file handles and directory handles use their own variables, and the names do not clash.
6:What does the permissions argument to mkdir do?
A6: The argument to mkdir determines the permissions that directory will have. On Unix, those permissions follow the usual format of read, write, and execute access for owner, group and all; on Mac and Windows, the permissions argument isn't useful, but you have to include it anyway (use 0777 and everything will work fine).

Exercises

1:Write a script that reads in a list of files from the current directory and prints them in alphabetical order. If there are directories, print those names with a slash (/) following them.
A1: Here's one answer:
#!/usr/ bin/perl -w
use strict;
use Cwd;

my $curr = cwd();
opendir(CURRDIR, $curr) or die "can't open directory ($!), exiting.
";

my @files = readdir(CURRDIR);
closedir(CURRDIR);

foreach my $file (sort @files) {
    if (-d $file) {
        print "$file/
";
    }
    else { print "$file
"; }
}

2:BUG BUSTER: This script is supposed to remove all the files and directories from the current directory. It doesn't. Why not?
while (<foo*>) {
   unlink $_;
}

A2: The unlink function is only used to remove files. Use rmdir to remove directories. If the goal, per the description, is to remove all the files and directories in the directory, you'll need to test each filename to see if it's a file or directory and call the appropriate function.
3:BUG BUSTER: How about this one?
#!/usr/ bin/perl -w

opendir(DIR, '.') or die "can't open directory ($!), exiting.
";
while (readdir(DIR)) {
  print "$_
";
}
closedir(DIR);

A3: The bug lies in the test for the while loop; the assumption here is that readdir inside of a while loop assigns the next directory entry to $_, the same way that reading a line of input from a file handle does. This is not true. For readdir you must explicitly assign the next directory entry to a variable, like this:
while (defined($in = readdir(DIR))) { ... }

4:Write a script that gives you a menu with five choices: create a file, rename a file, delete a file, list all files, or quit. For the choice to create a file, prompt the user for a filename and create that file (it can be empty) in the current directory. For the rename and delete operations, prompt for the old file to rename or delete; also for rename, prompt for the new name of the file and rename it. For the choice to list all files, do just that. SUGGESTION: You don't have to bother with handling directories. EXTRA CREDIT: Do error checking on all filenames to make sure you're not creating a file that already exists, or deleting/renaming a file that doesn't exist.
A4: Here's one example. Pay particular attention to the &getfilename() subroutine, which handles error checking to make sure the file that was entered doesn't already exist (for creating a new file) or does actually exist (renaming or deleting a file).
#!/usr/ bin/perl -w
use strict;

my $choice = '';
my @files = &getfiles();

while ($choice !~ /q/i) {
    $choice = &printmenu();
  SWITCH: {
      $choice =~ /^1/ && do { &createfile(); last SWITCH; } ;
      $choice =~ /^2/ && do { &renamefile(); last SWITCH; } ;
      $choice =~ /^3/ && do { &deletefile(); last SWITCH; } ;
      $choice =~ /^4/ && do { &listfiles(); last SWITCH; } ;
      $choice =~ /^5/ && do { &printhist(); last SWITCH; } ;
  }
}

sub printmenu {
    my $in = "";
    print "Please choose one (or Q to quit): 
";
    print "1. Create a file
";
    print "2. Rename a file
";
    print "3. Delete a file
";
    print "4. List all files
";
    while () {
        print "
Your choice --> ";
        chomp($in = <STDIN>);
        if ($in =~ /^[1234]$/ || $in =~ /^q$/i) {
            return $in;
        }  else {
            print "Not a choice.  1<!->4 or Q, please,
";
        }
    }
}
sub createfile {
    my $file = &getfilename(1);

    if (open(FILE,">$file")) {
        print "File $file created.

";
        @files = &getfiles();
        close(FILE);
    }  else {
        warn "Cannot open $file ($!).
";
    }
}

sub renamefile {
    my $file = &getfilename();
    my $in = '';

    print "Please enter the new filename: ";
    chomp($in = <STDIN>);

    if (rename $file,$in) {
        print "File $file renamed to $in.
";
        @files = &getfiles();
    }  else {
        warn "Cannot rename $file ($!).
";
    }
}

sub deletefile {
    my $file = &getfilename();

    if (unlink $file) {
        print "File $file removed.
";
        @files = &getfiles();
    }  else {
        warn "Cannot delete $file ($!).
";
    }
}

sub getfilename {
    my $in = '';

    # call with no args to make sure the file exists
    my $new = 0;

    # call with an arg to make sure the file *doesn't* exist
    if (@_) {
       $new = 1;
    }

    while (!$in) {
        print "Please enter a filename (? for list): ";
        chomp($in = <STDIN>);
        if ($in eq '?') {
            &listfiles();
            $in = '';
        }  elsif ((grep /^$in$/, @files) && $new) {
            # file exists, not a new file, OK
            # file exists, new file: error
            print "File ($in) already exists.
";
            $in = '';
        }  elsif ((!grep /^$in$/, @files) && !$new) {
            # file doesn't exist, new file, OK
            # file doesn't exist, not a new file: error
            print "File ($in) not found.
";
            $in = '';
        }
    }
    return $in;
}


sub getfiles {
    my $in = '';
    opendir(CURRDIR, '.') or die "can't open directory ($!), exiting.
";
    @files = readdir(CURRDIR);
    closedir(CURRDIR);
    return @files;
}

sub listfiles {
    foreach my $file (@files) {
        if (-f $file) { print "$file
"; }
    }
    print "
";
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset