Permission Denied error when moving files - Perl

Discussion in 'Perl Misc' started by Ken, Nov 10, 2006.

  1. Ken

    Ken Guest

    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
    > 1

    ? "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
     
    Ken, Nov 10, 2006
    #1
    1. Advertising

  2. Ken

    J. Gleixner Guest

    Ken wrote:
    >[...] 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: $!";
     
    J. Gleixner, Nov 10, 2006
    #2
    1. Advertising

  3. Ken

    Ken Guest

    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" <>
    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: $!";
     
    Ken, Nov 10, 2006
    #3
  4. Ken

    -berlin.de Guest

    Ken <> wrote in comp.lang.perl.misc:
    > 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
     
    -berlin.de, Nov 10, 2006
    #4
  5. Ken

    J. Gleixner Guest

    Ken wrote:
    > 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: $!";
     
    J. Gleixner, Nov 10, 2006
    #5
  6. Ken

    Ken Guest

    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
     
    Ken, Nov 10, 2006
    #6
  7. On Nov 10, 6:22 pm, -berlin.de wrote:
    > Ken <> wrote in comp.lang.perl.misc:
    > > 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");


    But, Anno, the directory $cwd is the CWD.
     
    Brian McCauley, Nov 10, 2006
    #7
  8. On Nov 10, 6:31 pm, "J. Gleixner" <>
    wrote:
    > Ken wrote:
    >
    > > unless (-d '$newpgcount')

    >
    > 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.
     
    Brian McCauley, Nov 10, 2006
    #8
  9. Ken

    Ken Guest

    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
     
    Ken, Nov 10, 2006
    #9
  10. Ken

    -berlin.de Guest

    Brian McCauley <> wrote in comp.lang.perl.misc:
    >
    >
    > On Nov 10, 6:22 pm, -berlin.de wrote:
    > > Ken <> wrote in comp.lang.perl.misc:
    > > > 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");

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


    Oh, right. The only case where the file name doesn't need the directory
    prefix.

    Anno
     
    -berlin.de, Nov 10, 2006
    #10
  11. Ken

    Ken Guest

    > 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
     
    Ken, Nov 10, 2006
    #11
  12. Ken wrote:
    > 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
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
     
    John W. Krahn, Nov 10, 2006
    #12
  13. Ken

    Ken Guest

    > > 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
     
    Ken, Nov 10, 2006
    #13
  14. Ken

    Ken Guest

    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
     
    Ken, Nov 10, 2006
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Goblin
    Replies:
    1
    Views:
    8,461
  2. Alexander Magidow
    Replies:
    0
    Views:
    121
    Alexander Magidow
    Apr 4, 2004
  3. Nicolas D

    Permission denied with PERL/APACHE

    Nicolas D, May 9, 2004, in forum: Perl Misc
    Replies:
    7
    Views:
    209
    Walter Roberson
    May 11, 2004
  4. Piet L.
    Replies:
    1
    Views:
    153
    Brian McCauley
    Feb 24, 2005
  5. Replies:
    3
    Views:
    697
    alpha_beta_release
    Aug 24, 2006
Loading...

Share This Page