Deleting

How can I delete a folder specified on my server, and all the files in it?
cdc_sickleAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
jyu_88Connect With a Mentor Commented:
`unlink` to delete file
`rmdir` to remove empty folder.
So, to do what you want, you'd implement a sub, which has recursive call to itself to remove file inside it first then remove the folder.

sub RemoveDir() {
my $rootDir = $_[0];
my @dirEnt = ();
return -1 unless -d $rootDir;
opendir TOGODIR, $rootDir or return -1;
@dirEnt = grep !/\.\.?$/, readdir TOGODIR;
foreach $ent(@dirEnt) {
$ent = $rootDir."/".$ent;
if ( -f $ent) { unlink $ent }
if ( -d $ent) { &RemoveDir($ent) }
}
return 0
}


or you can use system("rm", "-rf", "togofolder") to use whatever command available from the operating system.
0
 
maneshrCommented:
try this.

i am assuming you are working on a UNIX based system.
the same code with slight changes would work for a Windows based system too!!

===========my_delete.pl
#!/usr/bin/perl

print qq{
Usage: $0 <directory1> <directory 2> ....
  - Removes ALL files in that directory
} if $#ARGV<0;
   
$DEBUG=0;

foreach $dir (@ARGV){
  push @dir,$dir;
 
  while ($dirs=pop @dir){
    $whereami=`pwd`;
    chomp($whereami);
    chomp($dirs);
    chdir $dirs;
    print "CHANGING to $dirs\n";
     
    while (<*>) {
      next if ($_ eq ".");
      next if ($_ eq "..");
      if (-d $_) {  ##  This entry is a directory, ignore it!!
        next if (-l $_);
        print "\t Dir-> ",$_,"\n" if $DEBUG;
        #push @dir,$dirs."/".$_;
      } elsif (-l $_) { ##  This entry is a SYMBOLIC LINK file, ignore it!!

       next;
      } elsif (-f $_) { ##  This entry is a PLAIN file, pick it!!
        print "\t Deleting File-> ",$_,"\n" if $DEBUG;

        ##  Try and delete the file
        $count=unlink $_;
        if ($count){  ##  YESSS!! File was deleted
          print "$_ Deleted!!\n";
        }else{
          print "$_ NOT Deleted!!\n";

        }
      }
    }
    exit if $DEBUG;
    chdir $whereami;
  }
============================
0
 
cdc_sickleAuthor Commented:
for both of you... What variable to i use to tell it which directory to delete?
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
ozoCommented:
use File::Path;
rmtree(['foo/bar/baz', 'blurfl/quux'], 1, 1);
0
 
cdc_sickleAuthor Commented:
Please explain that, i do not understand it.
0
 
ozoCommented:
perldoc File::Path
          NAME
                 File::Path - create or remove a series of directories

          SYNOPSIS
                 use File::Path

                 mkpath(['/foo/bar/baz', 'blurfl/quux'], 1, 0711);

                 rmtree(['foo/bar/baz', 'blurfl/quux'], 1, 1);

          DESCRIPTION
                 The  mkpath  function  provides a convenient way to create
                 directories, even if your mkdir kernel call  won't  create
                 more  than one level of directory at a time.  mkpath takes
                 three arguments:

                     the name of the path to create, or a  reference  to  a
                     list of paths to create,

                     a  boolean  value,  which if TRUE will cause mkpath to
                     print the name of each  directory  as  it  is  created
                     (defaults to FALSE), and

                     the  numeric mode to use when creating the directories
                     (defaults to 0777)

                 It  returns  a  list   of   all   directories   (including
                 intermediates,  determined  using  the Unix `/' separator)
                 created.

                 Similarly, the rmtree function provides a  convenient  way
                 to  delete  a  subtree  from the directory structure, much
                 like  the  Unix  command  rm  -r.   rmtree   takes   three
                 arguments:

                     the root of the subtree to delete, or a reference to a
                     list of roots.  All of the files and directories below
                     each  root,  as  well as the roots themselves, will be
                     deleted.

                     a boolean value, which if TRUE will  cause  rmtree  to
                     print  a  message each time it examines a file, giving
                     the name of the  file,  and  indicating  whether  it's
                     using  rmdir  or  unlink  to  remove  it, or that it's
                     skipping it.  (defaults to FALSE)
                     a boolean value, which if TRUE will  cause  rmtree  to
                     skip  any files to which you do not have delete access
                     (if running under VMS) or  write  access  (if  running
                     under  another  OS).   This  will change in the future
                     when a criterion for  `delete  permission'  under  OSs
                     other than VMS is settled.  (defaults to FALSE)

                 It  returns  the  number  of  files  successfully deleted.
                 Symlinks are treated as ordinary files.

                 NOTE: If the  third  parameter  is  not  TRUE,  rmtree  is
                 unsecure  in  the  face of failure or interruption.  Files
                 and directories which were not deleted may  be  left  with
                 permissions  reset  to  allow world read and write access.
                 Note also that the occurrence of errors in rmtree  can  be
                 determined  only  by  trapping  diagnostic  messages using
                 $SIG{__WARN__}; it is not apparent from the return  value.
                 Therefore,  you  must  be  extremely  careful  about using
                 rmtree($foo,$bar,0 in  situations  where  security  is  an
                 issue.

          AUTHORS
                 Tim   Bunce   <Tim.Bunce@ig.co.uk>   and   Charles  Bailey
                 <bailey@genetics.upenn.edu>

          REVISION
                 Current $VERSION is 1.0401.


0
 
cdc_sickleAuthor Commented:
so would it be:

rmtree(['usr/htdocs/usindex/folderdelete, '??'], 1, 1);

folder delete is the folder i want to delete with files in it too.
0
 
ozoCommented:
rmtree('/usr/htdocs/usindex/folderdelete', 1, 1);
0
 
maneshrCommented:
"What variable to i use to tell it which directory to delete?"

in order to find out whether of not to delete the directory you will have to first find out how many items (files, directories symbolic links ) are originally present in the  directory that you want to delete. then, as the deletion of files is going on, you will have to count the no of files that were deleted.

if these 2 counts are equal only then can you remove the directory.

Therefore first you will have to decide on the rules for removing the directory and look at the various scenarios.
0
 
cdc_sickleAuthor Commented:
rmtree('/usr/htdocs/usindex/folderdelete', 1, 1);

This doesn't seem to do anything... I have it running in a sub, and the sub does run because it displayes some text... But i look back at the folder and it is still their. Keep in mind, the folder was originally created by a script, ("nobody") so i thought it could be deleted by a script.
0
 
maneshrCommented:
here is the updated code...

#!/usr/bin/perl

print qq{
Usage: $0 <directory1> <directory 2> ....
  - Removes ALL files in that directory
} if $#ARGV<0;

$DEBUG=0;
$starting_dir=`pwd`;
chomp($starting_dir);

foreach $dir (@ARGV){
  push @dir,$dir;

  while ($dirs=pop @dir){
    $whereami=`pwd`;
    chomp($whereami);
    chomp($dirs);
    chdir $dirs;
    print "CHANGING to $dirs\n";

    while (<*>) {
      next if ($_ eq ".");
      next if ($_ eq "..");
      if (-d $_) {  ##  This entry is a directory, ignore it!!
        next if (-l $_);
        print "\t Dir-> ",$_,"\n" if $DEBUG;
       #push @dir,$dirs."/".$_;
      } elsif (-l $_) { ##  This entry is a SYMBOLIC LINK file, ignore it!!
        next;
      } elsif (-f $_) { ##  This entry is a PLAIN file, pick it!!
        print "\t Deleting File-> ",$_,"\n" if $DEBUG;

        ##  Try and delete the file
        $count=unlink $_;
        if ($count){  ##  YESSS!! File was deleted
          print "$_ Deleted!!\n";
        }else{
          print "$_ NOT Deleted!!\n";

        }
      }
    }
    exit if $DEBUG;

    if (chdir $starting_dir){ ##  Changed to the proper dir
      if (rmdir $dirs){ ##  Directory was successfully removed !!
        print "$dirs Removed\n";
      }else{
        print "$dirs NOT Removed: $!\n";
      }
    }else{
      print "Could not change to $starting_dir $!\n";
    }
    chdir $whereami;
  }
}
0
 
cdc_sickleAuthor Commented:
Ok, well how do i tell it the directory to delete... And why do you have two directories?
0
 
maneshrCommented:
(rmdir $dirs)

will delete the directory and also check if the delete was successfull.

the reason i am using 2 dirs is because i cannot be in a directory & delete it at the same time.
so before i start doing anything i store my current directory.
next i delete the files and then i change to the original directory and delete the other directory.

Hope that helps.
0
 
cdc_sickleAuthor Commented:
You still did not tell me where to specify the directory to be deleted!
0
 
maneshrCommented:
you have to pass the directory that you want to delete as a parameter to this script.

in fact if you just run the script, it will give you a brief help message about its usage.

Eg.

my_delete.pl /tmp

in the above you want to delete a single directory
OR

my_delete.pl /directory1 /directory2 etc...


in the above you can delete multiple directories.

0
 
cdc_sickleAuthor Commented:
yeah, well i want to put this in a sub in my current script right now. how would i pass in directories like that?
0
 
maneshrCommented:
change the code as follows


&rmtree("usr/htdocs/usindex/folderdelete");

sub  {
  ($which_dir)=@_;

  push(@list_of_dirs,$which_dir);
##print qq{
##                   Usage: $0 <directory1> <directory 2> ....
##                     - Removes ALL files in that directory
##                   } if $#ARGV<0;

  $DEBUG=0;
  $starting_dir=`pwd`;
  chomp($starting_dir);

  foreach $dir (@list_of_dirs){
    push @dir,$dir;
.......

}
0
 
PC_User321Commented:
Have you tried
   `/usr/bin/rm -R $Directory`

Obviously the script must have sufficient permissions.
0
 
PC_User321Commented:
>> This doesn't seem to do anything...
Sounds as if your delete script does not have sufficient permissions.

To check permissions, run the script below.  It should create directories and then delete them.  That should work without problems.  It proves that the deletion mechanism works.
Then split the file into a 'copy' part and and a 'delete' part.  Put the copy part into your 'nobody' script, and put the 'delete' part where you want to do the deletion.  Run 'nobody', then the delete script.
If the deletion works, then your problem is solved.
If the deletion does not work, then the problem must be permissions.


#! /usr/local/bin/perl -w
$BaseDir = "/u/sickle/tempDir";
$DirToCopy = "/u/sickle/perl";
$DirToDelete = "/u/sickle/tempDir/perl";
print "Copying $DirToCopy to $BaseDir ...\n";
`/usr/bin/cp -r $DirToCopy $BaseDir`;
print Directory after copy ...\n";
print `ls $DirToDelete`;
`/usr/bin/rm -R $DirToDelete`;
print Directory after delete ...\n";
print `ls $DirToDelete`;
0
 
PC_User321Commented:
(Change the paths to suit your system)
0
 
cdc_sickleAuthor Commented:
madonna:/usr/home/usindex/www$ perl delete.cgi
Copying /usr/htdocs/www/usindex/States/Texas/Houston/Categories/Food_Restaurants
/Italian_Restaurants/Moderate/test to /usr/www/htdocs/usindex ...
Can't exec "/usr/bin/cp": No such file or directory at delete.cgi line 6.
Directory after copy ...
ls: /usr/htdocs/www/usindex/States/Texas/Houston/Categories/Food_Restaurants/Ita
lian_Restaurants/Moderate/test: No such file or directory
Can't exec "/usr/bin/rm": No such file or directory at delete.cgi line 9.
Directory after delete ...
ls: /usr/htdocs/www/usindex/States/Texas/Houston/Categories/Food_Restaurants/Ita
lian_Restaurants/Moderate/test: No such file or directory
0
 
jyu_88Commented:
add my RemoveDir Sub routine into your code,
then, call it when you are ready to purge a directory, supposed named '/home/maneshr/togoDir',
&RemoveDir("/home/maneshr/togoDir);

my RemoveDir sub shown above is just a simplfied version of  rmtree from File::Path pointed by Ozo.
0
 
cdc_sickleAuthor Commented:
Hey jyu!!! It worked, well, it deleted all the files in the directory, but it didn't delete the folder... Wierd, if you can answer that, ill give you another 50 points. Otherwise ill just give you the 50.
0
 
jyu_88Commented:
darn me, I forgot to remove the rootDir itself, add a line right before 'return 0' in the sub RemoveDir definition.


foreach $ent(@dirEnt) {
                $ent = $rootDir."/".$ent;
                if ( -f $ent) { unlink $ent }
                if ( -d $ent) { &RemoveDir($ent) }
                }
                return 0
                }
}
# ha, remove the rootDir itself. <<<<<<<<<<<
unlink $rootDir;

return 0
}

That will do it.
0
 
jyu_88Commented:
oops, the new line should be:
rmdir $rootDir;

instead of
unlink $rootDir;
0
 
cdc_sickleAuthor Commented:
do i need the return 0's?
0
 
cdc_sickleAuthor Commented:
Adjusted points to 100
0
 
cdc_sickleAuthor Commented:
Thanks man!
0
 
jyu_88Commented:
return 0 is to feed back status of the call to this sub routine (or function as in C, or method as in Java, C++). This way, the caller program can tell if the call is succesful or not, if not, then what error is encoutered can be distinguished by different error code you defined yourself.

To capture the status, in your main program,
$status = &RemoveDir("/home/dirToGo");
if ( 0 == $status ) {       print "OK: RemoveDir succesful\n"}
else { print "Warning: error trying to remove /home/dirToGo. Error code: $status\n"
# more action for different error status.
}


To make the return statement really useful, you'd add more error-check stuff into the sub definition.
0
 
cdc_sickleAuthor Commented:
Well, i just put it in a cgi script, and returned some html code, and took out the return 0. So its fine.
0
All Courses

From novice to tech pro — start learning today.