ytjPerl has asked for the wisdom of the Perl Monks concerning the following question:

Hi Folks, I am trying to delete folder and its contents with plain perl, as I am not able to install perl module on my environment.
my $result = system('del "C:\Users\tyj\Documents\Traning\2017\*"'); my $result = system('rmdir "C:\Users\tyj\Documents\Traning\2017"');
When I ran this script, it prompt up to confirm to delete files, So I need to type 'y' to confirm. However, I need this as an automation job. I tried system('del -y "C:\Users\tyj\Documents\Traning\2017\*"'); but I do not think this works, Any idea of it? Thanks

Replies are listed 'Best First'.
Re: delete folder and its content with plain perl
by LanX (Saint) on Nov 06, 2017 at 20:19 UTC
Re: delete folder and its content with plain perl
by roboticus (Chancellor) on Nov 06, 2017 at 20:59 UTC

    ytjPerl:

    Perhaps you could use:

    system("cmd", "/c", "del", "-y", "C:\\Users\\tyj\\Documents\\Traning\\ +2017\\*");

    The way you tried it wouldn't work because:

    1. del is a built-in command as part of the command shell, so system() won't find it.
    2. You're not taking the command-line quoting rules into account.

    The (untested) system command I showed above tells Windows to run the command shell (cmd) for a single command (/c). The rest of the arguments are the ones you showed in your last example, but I fixed the backslashes for you.

    As others have mentioned, it's not pure perl, or more precisely, it isn't portable across operating systems because we're shelling out to a command shell to do the work.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: delete folder and its content with plain perl
by Laurent_R (Canon) on Nov 06, 2017 at 22:43 UTC
    Hi ytjPerl

    Some of the modules you might want to use for your purpose (including File::Path already mentioned by LanX) are core modules (i.e. most probably already installed on your platform). Use them insofar as possible.

    Assuming you really can't use these modules and that you want pure Perl, you could try this recursive subroutine:

    sub deldir { my $dir = shift; my @entries = glob "$dir/*"; for my $entry (@entries) { unlink $entry if -f $entry; deldir($entry) if -d $entry; } rmdir $dir; } my $dir_to_be_deleted = 'C:\Users\tyj\Documents\Traning\2017'; deldir $dir_to_be_deleted;
    CAVEAT:

    1. I haven't tested it;

    2. You might have to change some things (such as "$dir/*" to "$dir\\*") under Windows (probably not needed, though);

    3. Make sure you fully understand how it works before trying to use it: this subroutine is designed to wipe out a full directory tree, and it could possibly delete your entire filesystem if wrongly used;

    4. Last, BUT NOT LEAST, YOU SHOULD THOROUGHLY TEST it on dummy directories before you proceed.

    In view of the above warnings, please read carefully the following notice:

    This subroutine is provided "as is", without any warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with this subroutine or the use or other dealings in this subroutine.

Re: delete folder and its content with plain perl
by hippo (Archbishop) on Nov 06, 2017 at 23:35 UTC
Re: delete folder and its content with plain perl
by salva (Canon) on Nov 07, 2017 at 10:55 UTC
    Windows has a help command:
    C:\>help rmdir Removes (deletes) a directory. RMDIR [/S] [/Q] [drive:]path RD [/S] [/Q] [drive:]path /S Removes all directories and files in the specified directo +ry in addition to the directory itself. Used to remove a dir +ectory tree. /Q Quiet mode, do not ask if ok to remove a directory tree wi +th /S

      I had thought roboticus was probably right about requiring cmd /c. So I thought salva's answer wasn't enough; but it turns out to be right (sorry for doubting you, ++salva): you don't need the cmd /c, and all you need is to provide the proper switches to rmdir:

      C:\Temp>mkdir delme.dir\subdir C:\Temp>dir /S delme.dir Volume in drive C is System Volume Serial Number is ... Directory of C:\Temp\delme.dir 11/07/2017 06:44 AM <DIR> . 11/07/2017 06:44 AM <DIR> .. 11/07/2017 06:44 AM <DIR> subdir 0 File(s) 0 bytes Directory of C:\Temp\delme.dir\subdir 11/07/2017 06:44 AM <DIR> . 11/07/2017 06:44 AM <DIR> .. 0 File(s) 0 bytes Total Files Listed: 0 File(s) 0 bytes 5 Dir(s) 45,598,023,680 bytes free C:\Temp>perl -le "print system(qq(rmdir delme.dir)) && $! || 'deleted' +" The directory is not empty. No such file or directory C:\Temp>perl -le "print system(qq(rmdir /S delme.dir)) && $! || 'delet +ed'" delme.dir, Are you sure (Y/N)? n No such file or directory C:\Temp>perl -le "print system(qq(rmdir /S /Q delme.dir)) && $! || 'de +leted'" deleted C:\Temp>dir /S delme.dir Volume in drive C is System Volume Serial Number is ... File Not Found

      But ytjPerl should also study/learn from the other responses, because TIMTOWTDI. And if you are sticking with system, use the multi-argument version that roboticus showed, and beware of quoting and backslashes. My oneliners above were for ease of typing, and to prove salva's point, not for robust and good coding style.

        pryrt:

        Yeah, I probably should have elaborated on that a bit. As you probably know CMD.EXE shell has some commands built into it, so there are no EXE versions of some commands you'd expect to find. I should've mentioned to the OP that adding the "cmd", "/c" arguments are to let you tell the CMD shell to execute a built-in command. For commands with external EXE files (such as RMDIR.EXE) it wouldn't be helpful.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

      I am trying to use  my $result =  system ( 'rmdir /S /Q "$foldername"'); to delete the folder I created earlier in my script. But I got the error message that system cannot find the path. Do you know the problem here? I used both with quote and without. Thanks

        ytiPerl:

        Inside single quotes, a variable is not expanded, so you're running "rmdir /S /Q $foldername".

        Try changing it to:

        my $result = system("rmdir /S /Q $foldername");

        Of course, if you have backslashes or spaces in the $foldername variable, then you'll get other problems. That's why you might want to consider using the list version of the system command, like:

        my $result = system('rmdir', '/S', '/Q', $foldername);

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: delete folder and its content with plain perl
by thanos1983 (Parson) on Nov 07, 2017 at 09:47 UTC

    Hello ytjPerl,

    It looks the fellow Monks have provided proposed solutions already. Never the less to add something minor here just for reference purposes.

    Your question has been asked / answered before, see Removing Directory and Contents with Perl.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: delete folder and its content with plain perl
by karlgoethebier (Abbot) on Nov 07, 2017 at 17:49 UTC

    I don't have windoz at hand no more but i think remove_tree from File::Path should do the job.

    Run corelist File::Path from cmd to see if you have it.

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: delete folder and its content with plain perl
by ytjPerl (Scribe) on Nov 08, 2017 at 15:11 UTC
    salva is correct. My script is like this
    my $result = system('rmdir /S /Q "C:\Users\tyj\Documents\Traning\2017" +');
    I am able to delete this directory tree without any confirmation. Thanks
Re: delete folder and its content with plain perl
by ytjPerl (Scribe) on Nov 09, 2017 at 16:51 UTC
    My path is still having problems. I am trying to delete archive log, when I do this - system ('rmdir /S /Q "D:\log_script\Archive\2017-10-14.zip"'); directory is invalid do this - system ('rmdir /S /Q "D:/log_script/Archive/2017-10-14.zip"'); system cannot find the path do this -
    my $DIR = "D:/log_script/Archive"; my @files = glob("$DIR/*.zip"); for my $file (@files) { next unless -f $file; my $age = -M $file; if ($age > 1 ) { print "$file \n"; system ( 'rmdir', '/S', '/Q', "$file"); } }
    invalid switch - "log_script" anyone have idea?

      The error probably has to do with the use of forward slashes in the filename, which appear to be interpreted as switches by rmdir.

      I strongly recommend you use remove_tree from File::Path, as several others have suggested. It has been a core module for over 20 years and should therefore not only meet your requirement of being "plain Perl", but unlike rmdir it is also platform-independent!

      Also, note that you probably don't want to use a "delete directory" function to delete individual files. See unlink for files.