in reply to Re^6: Remove Script for a Infrastructure file managenet system running embedded perl
in thread Remove Script for a Infrastructure file managenet system running embedded perl

sanju7:

I downloaded your code so I could study it in more detail. Here are some things I noticed:

At this point, I had:

#! /usr/bin/perl -w use strict; use diagnostics; use File::Find; # Variable "ThisMoveTarget" contains destination archive location # path. If this stores a path (i.e if directories are archived) # then the main body of code (i.e walk down the source location # for deleting empty directories) should execute # my $ThisMoveTarget = q|holds location where archive files # should go |; my $ThisMoveTarget = '/home/ssaha/tmp/archive'; # our $DelEmptyFoldrArchive = q|holds yes or no |; our $DelEmptyFoldrArchive = "yes "; # our $ThisSourceDirectory = q|holds the source file location |; our $ThisSourceDirectory = "/home/ssaha/tmp/source/"; #our $ThisSourceDirectory = "\\\\hostname\\share-test"; my $file ; if ($DelEmptyFoldrArchive eq "yes ") { print STDERR "Debug3: entering check1 \n" ; find({ wanted => \&wanted, no_chdir => 1 }, $ThisSourceDirectory); if ($file) { print STDERR "Debug3: entering check2 file is file \n" ; print STDERR "The $ThisSourceDirectory has files present \n" ; } elsif (!$file) { print STDERR "Debug3 entering check3 file is no file\n" ; finddepth (sub { print "rmdir $_\n"; }, $ThisSourceDirectory); } } else { print STDERR "Debug3: entering check5 \n" ; print STDERR "DelEmptyFoldrArchive is $DelEmptyFoldrArchive, skippi +ng directory deletion. \n" ; } sub wanted { return unless -f; $file = $_; print STDERR "$file \n " ; }

At this point, the code is pretty clear, and one of the errors is apparent: Some of the code you probably intended to be in the wanted subroutine was actually following it, so it only checked the last file found at that part. The my $file; declaration was at the outermost scope, and hid that from you. By moving the declaration inside of sub wanted (along with the associated code), it cleans things up a bit more.

I stopped at this point for now, so you can work a little more on it.

Another note: perl works well with forward slashes in paths, even under Windows. You may find it helpful (as I do) to always use forward slashes in paths. It helps portability and you can avoid the headache of quoting backslashes.

...roboticus

Replies are listed 'Best First'.
Re^8: Remove Script for a Infrastructure file managenet system running embedded perl
by sanju7 (Acolyte) on Jul 22, 2010 at 21:30 UTC

    Roboticus:

    Thanks for your valuable input.

    About forward slashes: I just included the part of my code which was accidentally excluded. I am dealing with user input and most times its two backslashes forwarded by server name and share (\\hostname\share-dir\ ).

    Also i think the area where the thing going wrong at Linux environment is the rmdir $_ is feeding the directory name only and not the full path with the name.

    I am getting script output like below, i added a print statement inside "findpath" like below, print " directories are $_ \n";

    directories are folder directories are dir2 directories are folder directories are dir3 directories are folder directories are dir1 directories are .

    How can i make sure the find path function returns full path for every empty directory?

      sanju7:

      The documentation for the wanted function interface for File::Find shows that it uses three variables to communicate with the function:

      • $File::Find::dir is the current directory name,
      • $_ is the current filename within that directory, and
      • $File::Find::name is the complete pathname to the file.

      So just use $File::Find::name instead of $_ to get the complete path name.

      ...roboticus

        Roboticus

        Using $File::Find::name rather has undesired effects.
        #! /usr/ddsperl/bin/perl -w # Testing # Author: #use strict; use diagnostics; use File::Find; # Variable "Error" contains any error of previous task runs. # Variable "ThisMoveTarget" contains destination archive location path +. If this stores a path (i.e if directories are archived) then # the main body of code (i.e walk down the source location for deletin +g empty directories) should execute my $Error = "0" ; # my $ThisMoveTarget = q|holds location where archive files should go +|; my $ThisMoveTarget = '/home/ssaha/tmp/archive'; # our $DelEmptyFoldrArchive = q|holds yes or no |; our $DelEmptyFoldrArchive = "yes "; # our $DelEmptyFoldrArchive = "no "; # our $ThisSourceDirectory = q|holds the source file location |; our $ThisSourceDirectory = "/home/ssaha/tmp/source/"; #our $ThisSourceDirectory = "\\hostname\share-dir"; if ($ThisSourceDirectory =~ m/^\\\\/ ) { ($ThisSourceDirectory =~ s/[\\]/\\\\/g ) ; } my $file ; if (($DelEmptyFoldrArchive eq "yes ")&&($ThisMoveTarget)) { if (($ThisSourceDirectory)&&("$Error" == 0)) { find({ wanted => \&wanted, no_chdir => 1 }, $ThisSourceDirectory); sub wanted { return unless -f; $file = $_; print STDERR "$file \n " ; } if ($file) { print STDERR "The $ThisSourceDirectory has files pres +ent \n" ; } elsif (!$file) { finddepth (sub { print " directories are $File::Find::name \n"; rmdir $File::Find::name ; # rmdir $_ ; # rmdir }, $ThisSourceDirectory); } } elsif (($ThisSourceDirectory)&&("$Error" != 0)) { print STDERR "JOB Completed with Errors, Source Agent used was SRCHOST +\n" ; } } else { print STDERR "DelEmptyFoldrArchive is $DelEmptyFoldrArchive, + skipping directory deletion. \n" ; }

        When used File::Find::name with rmdir , it deletes the source directory itself ($ThisSourceDirectory=/home/ssaha/tmp/source ) upon condition being satisfied (empty directory) and not the constituent sub directories inside. The only two options i am finding safe is "rmdir $_" and "rmdir". Even though they are working as a code test on separate linux environ --on actual test script(code) is only able to delete on windows clients locally (c:\path etc format. Its not able to delete inputs such "\\hostname\share\" not even in Linux ("\usr\local\tmp") type. I think there a possibility that this is because of rmdir not getting full pathname and i am not getting how it could be achieved safely.

        output

        [scripts]# perl ./testArchive.pl directories are /home/ssaha/tmp/source/dir1/folder directories are /home/ssaha/tmp/source/dir1 directories are /home/ssaha/tmp/source/dir3/folder directories are /home/ssaha/tmp/source/dir3 directories are /home/ssaha/tmp/source/dir2/folder directories are /home/ssaha/tmp/source/dir2 directories are /home/ssaha/tmp/source [root@hostname scripts]# ls -l /home/ssaha/tmp/source ls: /home/ssaha/tmp/source: No such file or directory [root@nuuuniitsahalab scripts]# ls -l /home/ssaha/tmp/ total 0