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]