Permission Denied error when moving files - Perl

K

Ken

Hello,

I have a script that is reading the contents of a directory, only for
files with a *.PDF extension. Once the files names are read into a
list, the pdf's are looked at to determine the number of pages in the
file. Based on the number of pages, I'm wanting a new directory to be
created or used, if it already exists, and move the pdf files with the
matching number of pages into the directory. When trying to move/copy
& delete I get a Permission Denied error from the script.

Here's my script for you to review:
###########################
use strict;
use warnings;

use File::chmod;
use Cwd;
use Carp;
use Getopt::Long;
use PDF;
use POSIX;
use File::Copy;
use File::Basename;

# find out current working directory
my $cwd = getcwd;
#print "$cwd\n";

opendir(DIR, "$cwd") || die ("Unable to open directory");
my @pdfname = grep { /\.pdf$/ } readdir(DIR);
closedir(DIR);

# Find all files with "*.pdf" extension
#my @pdfname = glob("*.pdf");
my $pdfcount = @pdfname;
my $pdfFile;
if($pdfcount != 0)
{
foreach $pdfFile(@pdfname)
{
do_the_dirty_job_on($pdfFile);
}

}

exit(1);

sub do_the_dirty_job_on
{
my $file = shift;
my $PDFfile = PDF->new($file);
if ($PDFfile->IsaPDF)
{
print "File $file has ",$PDFfile->Pages," page",$PDFfile->Pages
? "s" :"","\n";
print $file,":",$PDFfile->Pages,"\n";
my $PDFPages = $PDFfile->Pages;
my $newpgcount = $PDFPages -2;
my $newfile;
unless (-d '$newpgcount')
{
mkdir($newpgcount);
$newfile = "/$newpgcount/$file";
move($file,$newfile) or die "move failed: $!";
#rename($file,$newfile) or die "move failed: $!";
#system("move","$file","/$newpgcount/$file") or die
"move failed:
$!";
#unlink($file) or die "delete failed: $!";
}
else
{
$newfile = "/$newpgcount/$file";
move($file,$newfile) or die "move failed: $!";
#rename($file,$newfile) or die "move failed: $!";
#system("move","$file","/$newpgcount/$file") or die
"move failed:
$!";
#unlink($file) or die "delete failed: $!";
}
}
else
{
print "File $file isn't a PDF file\n";
}
}

###########################

I have left in the commented lines that I have tried for you to see the
different steps that I have taken.

Thanks in advance for your help and advise.

--Ken
 
J

J. Gleixner

Ken said:
[...] When trying to move/copy
& delete I get a Permission Denied error from the script.

Here's my script for you to review:

Since PDF isn't your issue, narrow down the problem by
removing all the extra code, which will simplify the
issue for you and us.
my $newfile;
unless (-d '$newpgcount')
{
mkdir($newpgcount);
$newfile = "/$newpgcount/$file";

That initial '/' is probably the problem.
move($file,$newfile) or die "move failed: $!";

To see the issue, change that to a more helpful error message:

move( $file, $newfile )
or die "move( $file, $newfile ) failed: $!";
 
K

Ken

J. Gleixner,

Thanks for your reply.

Per your advise, below is the exact message from the command prompt:
##########
D:\Scripts>perl Copy_pdf_pages.pl
File mcp_1678576.pdf has 3 pages
mcp_1678576.pdf:3
move( mcp_1678576.pdf, D:\Scripts\1\mcp_1678576.pdf ) failed:
Permission denied
at Copy_pdf_pages.pl line 61.
##########

Line 61 contains: move($file,$newfile) or die "move( $file, $newfile )
failed: $!";.
I changed line 60 to this: $newfile = "$newpgcount/$file";.

I have tried moving the file in a command prompt and that worked fine,
so I'm baffled why Perl is not able to move the file.

Any other suggestions?

Thanks again for your help.

--Ken

On Nov 10, 11:21 am, "J. Gleixner" <[email protected]>
wrote:
Since PDF isn't your issue, narrow down the problem by
removing all the extra code, which will simplify the
issue for you and us.
my $newfile;
unless (-d '$newpgcount')
{
mkdir($newpgcount);
$newfile = "/$newpgcount/$file";

That initial '/' is probably the problem.
move($file,$newfile) or die "move failed: $!";

To see the issue, change that to a more helpful error message:

move( $file, $newfile )
or die "move( $file, $newfile ) failed: $!";
 
A

anno4000

Ken said:
Hello,

I have a script that is reading the contents of a directory, only for
files with a *.PDF extension. Once the files names are read into a
list, the pdf's are looked at to determine the number of pages in the
file. Based on the number of pages, I'm wanting a new directory to be
created or used, if it already exists, and move the pdf files with the
matching number of pages into the directory. When trying to move/copy
& delete I get a Permission Denied error from the script.

Here's my script for you to review:
###########################
use strict;
use warnings;

use File::chmod;
use Cwd;
use Carp;
use Getopt::Long;
use PDF;
use POSIX;
use File::Copy;
use File::Basename;

# find out current working directory
my $cwd = getcwd;
#print "$cwd\n";

opendir(DIR, "$cwd") || die ("Unable to open directory");

There's no need to quote $cwd. See perldoc -q quoting.

Incidentally, you don't need the working directory explicitly, '.'
will do nicely.
my @pdfname = grep { /\.pdf$/ } readdir(DIR);
closedir(DIR);

# Find all files with "*.pdf" extension
#my @pdfname = glob("*.pdf");
my $pdfcount = @pdfname;
my $pdfFile;
if($pdfcount != 0)

It's unnecessary to check for the existence of files. The loop below
will simply not run if there aren't any.
{
foreach $pdfFile(@pdfname)
{
do_the_dirty_job_on($pdfFile);
^^^^^^^^
This is probably your error. $pdfFile holds only the file name relative
to the directory $cwd. So to access the file, you'd need

do_the_dirty_job_on("$cwd/$pdfFile");

[rest snipped]

Anno
 
J

J. Gleixner

Ken said:
J. Gleixner,

Thanks for your reply.

Sure. Thanks in advance for not top-posting again. :)
Per your advise, below is the exact message from the command prompt:
##########
D:\Scripts>perl Copy_pdf_pages.pl
File mcp_1678576.pdf has 3 pages
mcp_1678576.pdf:3
move( mcp_1678576.pdf, D:\Scripts\1\mcp_1678576.pdf ) failed:
Permission denied
at Copy_pdf_pages.pl line 61.
##########

Line 61 contains: move($file,$newfile) or die "move( $file, $newfile )
failed: $!";.
I changed line 60 to this: $newfile = "$newpgcount/$file";.

I have tried moving the file in a command prompt and that worked fine,
so I'm baffled why Perl is not able to move the file.

I took at look at your script again..
unless (-d '$newpgcount')

Change that to:

unless( -d $newpgcount )

Also, if

$newpgcount=1;
$newfile = "$newpgcount/$file"

Then I'd think

die "move( $file, $newfile ) failed: $!";

Would print:

move( mcp_1678576.pdf, 1/mcp_1678576.pdf ) failed: Permission denied

but.. if the above change to your unless fails, then try something
simple, as I suggested before.

e.g. ensure the directory '1' exists and you have permissions to create
files there.

use File::Copy;
my $file = 'mcp_1678576.pdf';
my $newfile = "1/$file";
move( $file, $newfile )
or die "move( $file, $newfile ) failed: $!";
 
K

Ken

Anno,

Thanks for your reply.

In using your suggestions, the last item
"do_the_dirty_job_on("$cwd/$pdfFile");", ended up producing the file
error message from the CP:

############
D:\Scripts>perl Copy_pdf_pages.pl
File D:\Scripts\mcp_1678576.pdf has 3 pages
D:\Scripts\mcp_1678576.pdf:3
move(mcp_1678576.pdf, D:\Scripts\1\D:\Scripts\mcp_1678576.pdf) failed:
No such f
ile or directory at Copy_pdf_pages.pl line 75.

D:\Scripts>
############

Notice the destination move path:
"D:\Scripts\1\D:\Scripts\mcp_1678576.pdf".

In keeping with your suggestions, I began thinking that maybe Perl
needed the absolute path to pull in the pdf file for the subroutine,
but when moving, I only needed the file name, so I added another couple
of lines right before the point when I was going to move the file.
Here are the lines:

############
foreach $pdfFile(@pdfname)
{
#print "$cwd\\$pdfFile\n";
do_the_dirty_job_on("$cwd\\$pdfFile");
}

exit(1);

sub do_the_dirty_job_on
{
my $file = shift;
my $PDFfile = PDF->new($file);
if ($PDFfile->IsaPDF)
{
print "File $file has ",$PDFfile->Pages," page",$PDFfile->Pages > 1
? "s" :"","\n";
print $file,":",$PDFfile->Pages,"\n";
my $PDFPages = $PDFfile->Pages;
my $newpgcount = $PDFPages -2;
my $newfile;
my @nameonly = split(/\\/,$file); ######### splits by \\
my $filenameonly = $nameonly[2]; ######### Grab only the
filename
unless (-d $newpgcount)
{
mkdir($newpgcount);
$newfile = "$cwd\\$newpgcount\\$filenameonly";
move($filenameonly,$newfile) or die "move($filenameonly, $newfile)
failed: $!";
}
else
{
$newfile = "$cwd\\$newpgcount\\$filenameonly";
move($filenameonly,$newfile) or die "move($filenameonly, $newfile)
failed: $!";
}
}
}
############

This line of thinking didn't work. This time I got my same original
error message.

Thanks again.

--Ken
 
B

Brian McCauley

^^^^^^^^
This is probably your error. $pdfFile holds only the file name relative
to the directory $cwd. So to access the file, you'd need

do_the_dirty_job_on("$cwd/$pdfFile");

But, Anno, the directory $cwd is the CWD.
 
B

Brian McCauley

Change that to:

unless( -d $newpgcount )

Better still get rid of it altogether since you are not bothering to
check if the mkdir() succeded anyhow just let it fail if the directory
already exists.
 
K

Ken

J. Gleixner,

Thanks again for your reply.

In trying your last suggestions, with a simple move script, this worked
perfectly. Now with using those same fundamentals, I need to figure
out where the problem is starting in my current script.

The one thing that is consistantly working, is the creation or the
checking on the "1" directory. The change to the Unless, didn't seem
to make a different, but I did leave off the single quotes.

This is just so bizarre. It's probably something so simple that's
being missed! :)

--Ken
 
K

Ken

But, Anno, the directory $cwd is the CWD.

Correct, since I'm using the module CWD:getcwd. A poster from Tek-Tips
suggested that I use an explicit path variable versus the CWD to test
the results.

Thanks,

--Ken
 
J

John W. Krahn

Ken said:
J. Gleixner,

Thanks again for your reply.

In trying your last suggestions, with a simple move script, this worked
perfectly. Now with using those same fundamentals, I need to figure
out where the problem is starting in my current script.

The one thing that is consistantly working, is the creation or the
checking on the "1" directory. The change to the Unless, didn't seem
to make a different, but I did leave off the single quotes.

This is just so bizarre. It's probably something so simple that's
being missed! :)

I haven't used Windows in a while but it could be because the PDF module has
an open filehandle on the file and Windows will not let the file be modified
by another process while the file is in use?

Try something like:

my $PDFPages = do {
my $PDFfile = PDF->new( $file );
$PDFfile->IsaPDF ? $PDFfile->Pages : undef;
};

To limit the scope of the PDF object.



John
 
K

Ken

unless( -d $newpgcount )Better still get rid of it altogether since you are not bothering to
check if the mkdir() succeded anyhow just let it fail if the directory
already exists.

Brian,

Good point! I'll add some error checking to the mkdir line to make
sure it isn't failing for sure. Supposedly, by default, if you don't
add the permissions to the mkdir command, 0777 is added. Does this
work with Windows as well, especially since 0777 is Unix based?

Thanks,

--Ken
 
K

Ken

John,

You were right on target. The PDF was being held open and couldn't be
moved. What I ended up having to do was take the sub
"do_the_dirty_job_on" and make it strictly for determining where a file
was a PDF and getting the number of pages, then after that, call the
new sub "pdfmove", which contains the commands to move the pdfs. Some
of the variables, I needed to make global, but the problem is results.
Below is the new code to review.

################
use strict;
use warnings;

use File::chmod;
use Cwd;
use Carp;
use Getopt::Long;
use PDF;
use POSIX;
use File::Copy;
use File::Basename;

# find out current working directory
my $cwd = getcwd;
#print "$cwd\n";

opendir(DIR, "$cwd") || die ("Unable to open directory");
my @pdfname = grep { /\.pdf$/ } readdir(DIR);
closedir(DIR);

# Find all files with "*.pdf" extension
#my @pdfname = glob("*.pdf");
my $pdfcount = @pdfname;
my $pdfFile;
my $PDFPages;
my $file;

foreach $pdfFile(@pdfname)
{
#print "$cwd\\$pdfFile\n";
do_the_dirty_job_on("$cwd\\$pdfFile");
pdfmove();
}

sub do_the_dirty_job_on
{
$file = shift;
#print "File:$file\n";
my $PDFfile = PDF->new($file);
if ($PDFfile->IsaPDF)
{
#print "File $file has ",$PDFfile->Pages," page",$PDFfile->Pages > 1
? "s" :"","\n";
#print $file,":",$PDFfile->Pages,"\n";

$PDFPages = $PDFfile->Pages;
}
else
{
print "File $file isn't a PDF file\n";
}

}

sub pdfmove
{
my $newpgcount = $PDFPages -2;
my $newfile;
my @nameonly = split(/\\/,$file);
#print "NameOnly\: @nameonly\n";
my $filenameonly = $nameonly[2];
unless (-d $newpgcount)
{
mkdir("$newpgcount") or die "mkdir failed: $!";
$newfile = "$newpgcount/$filenameonly";
move($filenameonly,$newfile) or die "move($filenameonly, $newfile)
failed: $!";
#File::Copy::move($file,$newfile) or die "move failed: $!";
#rename($file,$newfile) or die "move failed: $!";
#system("move","$file","/$newpgcount/$file") or die "move failed:
$!";
#unlink($file) or die "delete failed: $!";
}
else
{
$newfile = "$newpgcount/$filenameonly";
move($filenameonly,$newfile) or die "move($filenameonly, $newfile)
failed: $!";
#File::Copy::move($file,$newfile) or die "move failed: $!";
#rename($file,$newfile) or die "move failed: $!";
#system("move","$file","/$newpgcount/$file") or die "move failed:
$!";
#unlink($file) or die "delete failed: $!";
}
}
################

BIG THANKS to everyone for their help and input!

--Ken
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top