On Thu, Aug 09, 2001 at 05:16:38AM -0700, perl newbie wrote:
> #!/usr/bin/perl -w
> use strict;
> use POSIX;
> 
> ##########################
> ###    MAIN PROGRAM    ###
> ##########################
> 
> 
> # set environment variables.
> 
> $ENV{WORK_AREA} = "/tmp/regr_tests";

Why are you using environmental variables for this?

 
> # forward declarations, required due to the use
> # of the "strict" pragma.
> 
> # variable declarations
> my $dir_name;
> my $cal_date = POSIX::strftime("%m%d%Y",localtime());
> my $proc_id = getpid();

Using $$ would be much easier than getpid().


> # function declarations
> sub myMkDir;
> 
> 
> # loop through the command line arguments and
> # check for the existence of the named directories.
> # Create new directories ONLY if they are not already
> # existing.
> 
>    foreach $dir_name (@ARGV){
> 
> # create unique directory names per each run.
>    $dir_name= "$dir_name" . "_". "$cal_date" . "_" .
> "$proc_id" ;
> 
>         myMkDir "$ENV{WORK_AREA}/$dir_name";
> 
> # recursively copy files from DB area to TEST area.
> system("/usr/bin/cp -rf \$HOME/samples
> \$ENV{WORK_AREA}/\$dir_name");
> }

You will very likely run into quoting problems with the shell; use the list
form of system:

    system(
        "/usr/bin/cp",
        "-rf",
        "$ENV{HOME}/samples",
        "$ENV{WORK_AREA}/$dir_name"
    );

You seem to be pretty confused about what variables are from Perl and what
are from the shell, and how to get one into the other.  $dir_name and
$ENV{WORK_AREA} are Perl variables, but they're being quoted in your code so
that the shell tries to interpolate them.

A better solution would be to do this in Perl, rather than rely on cp.  You
can do this with File::Find::find, File::Path::mkpath, and File::Copy::copy.

The following code is untested, I'm being lazy this morning.

    use File::Find qw(find);
    use File::Path qw(mkpath);
    use File::Copy qw(copy);
    use strict;


    # You will, of course, have to set $ENV{WORK_AREA} and $dir_name.
    my $source = "$ENV{HOME}/samples";
    my $target = "$ENV{WORK_AREA}/$dir_name";


    chdir($source)
        || die("Unable to change directory to \"$source\": \l$!.\n");

    find(\&wanted, ".");



    sub wanted {
        my $target_file = "$target/$File::Find::name";

        if (-d) {
            mkpath($target_file) ||
                warn("Unable to make path \"$target_file\".\n");
        } else {
            unless (copy($File::Find::name, "$target/$File::Find::name")) {
                warn(
                    "Unable to copy \"$File::Find::name\" to ",
                    "\"$target_file\": \l$!.\n"
                );
            }
        }
    }

That's the general gist of it.  Adapt as necessary.



> ### end of main
> 
> ##########################
> ####  Sub myMkDir     ####
> ##########################
> 
> sub myMkDir {
>   my $dir = shift;
> 
>   if (-e $dir) {
>     if (!(-d $dir)) {
>       # Exist, but not a directory, it's a file
>       die "Error: can't create directory $dir, a file
> of that name already exist
> s\n"; }
>      else { die "Error: can't create directory $dir, a
> directory of that name al
> ready exists\n"; }
>   } else {
>     mkdir $dir, 0755;
>   }
> }

You have a race condition in this code, the -e test.  The directory could be
created in between the time you test for its existence and when you get to
the mkdir.  You should replace both the -e and -d tests with a check of
mkdir's return value:

    mkdir($dir, 0755) || die("Error: can't create directory \"$dir\": \l$!.\n");


Michael
--
Administrator                      www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to