Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^6: Remove Script for a Infrastructure file managenet system running embedded perl

by sanju7 (Acolyte)
on Jul 21, 2010 at 21:11 UTC ( [id://850727]=note: print w/replies, xml ) Need Help??


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

Roboticus:

Your leads were genuine so i made few changes in the code .
#! /usr/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 $ThisSourceDirectory = q|holds the source file location |; our $ThisSourceDirectory = "/home/ssaha/tmp/source/"; #our $ThisSourceDirectory = "\\\\hostname\\share-test"; if ($ThisSourceDirectory =~ m/^\\\\/ ) { ($ThisSourceDirectory =~ s/[\\]/\\\\/g ) ; my $file ; if (($DelEmptyFoldrArchive eq "yes ")&&($ThisMoveTarget)) { if (($ThisSourceDirectory)&&("$Error" == 0)) { print STDERR "Debug3: entering check1 \n" ; find({ wanted => \&wanted, no_chdir => 1 }, $ThisSourceDirectory); sub wanted { return unless -f; $file = $_; print STDERR "$file \n " ; } if ($file) { print STDERR "Debug3: entering check2 file is file \n +" ; print STDERR "The $ThisSourceDirectory has files pres +ent \n" ; } # elsif ($file eq "") { elsif (!$file) { print STDERR "Debug3 entering check3 file is no file\n" ; finddepth (sub { rmdir $_; }, $ThisSourceDirectory); } } elsif (($ThisSourceDirectory)&&("$Error" != 0)) { print STDERR "Debug3 entering check4 \n" ; print STDERR "JOB Completed with Errors, Source Agent used was SRCHOST +\n" ; } } else { print STDERR "Debug3: entering check5 \n" ; print STDERR "DelEmptyFoldrArchive is $DelEmptyFoldrArchive, + skipping directory deletion. \n" ; }

Here activated the no_chdir flag of File::Find. Now i get the full file path. Also i tested with the shared path as well (//homename/share-dir/)type paths. Based on the observation i have applied a variable input modification to convert every shared path to (////hostname//share-dir//) type. Because given proper escape to the backslashes the code is able to stat the share paths. These are all good.

New Issue

Since last 3 days of testing shows the code is behaving differently in Windows and Linux depending upon where the agent is running them.

The above code does work fine when agent run them on,

(a) windows when the path are local (C:\dir\source)type path and cleans up the directories when the source directories are empty etc.

(b) But it still fails silently when agent runs them from Windows to (\\hostname\share-dir\) type paths.

(c) Also when agent is running in Linux its failing silently to remove (/usr/local/share-dir/) type paths.

A small check on all of these test conditions does detect that when code iterates through empty directory it goes through check1/3 (prints check1 and check3) i.e if operator does compare properly and brings it to the right loop, however it still doesn't do the cleaning.<\P>

Is it possible when the code iterates through empty directory and the $file becomes empty or (undef or 0) confusing the if operator and not running the rest of command on that curly brace properly ? In that case i have to test the $file variable on each time for undef or no value and null it or something i guess. What do you think ?

  • Comment on Re^6: Remove Script for a Infrastructure file managenet system running embedded perl
  • Download Code

Replies are listed 'Best First'.
Re^7: Remove Script for a Infrastructure file managenet system running embedded perl
by roboticus (Chancellor) on Jul 22, 2010 at 16:07 UTC

    sanju7:

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

    • You commented out use strict;. Usually, if commenting that out ever changes anything in your code, you should try to fix the offending line rather than suppressing the error message. In this case, uncommenting use strict didn't make any difference.
    • The $Error variable never changes, so I removed code that's never executed.
    • I found the indentation a bit confusing, so I reformatted the code a bit.
    • I moved the definition of sub wanted to the end (it was visually distracting to me).
    • I didn't want to arbitrarily remove files on my system, so I changed the rmdir statement to a print statement.
    • You're setting the values of $ThisMoveTarget and $ThisSourceDirectory in your code and not changing them, so I didn't see a need to test their values, so I removed those tests. (Obviously you'll want to keep the tests if you get the values from user input.)

    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

      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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://850727]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-25 08:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found