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

I have my own directory for my PERL scripts and most of my scripts log stuff. So my problem is that when I run a script to unlink all of the *.txt files, it doesn't do anything. Im using something among the lines of...
open(FILE,"/cgi and perl"); while(<FILE>){ unlink(<*.txt>); } close(FILE);
The problem is it doesn't get the job done when I run it through ActivePerl. Just a lead on what im doing wrong will be greatly appreciated.

Replies are listed 'Best First'.
Re: Unlinking...
by swiftone (Curate) on Nov 22, 2000 at 02:13 UTC
    The problem is that your unlink isn't targeted at the FILE filehandle. It's trying to delete from whereever the script was run, except that it never gets there, because you're opening a directory with a file open command. Use "or die ("File open error:$!");" on the open and I bet it'll die.

    You don't have to open files you are trying to delete. See unlink


    Update: Let's look at your script line by line:
    open(FILE,"/cgi and perl");
    Problems:
    1. You didn't test for a die condition.
    2. You are opening a directory for no real reason
    3. What you are trying for is done by opendir and readdir
    while(<FILE>){
    problems:
    1. This will read FILE line by line (except that it's a directory), and put the line in $_ (which would never be used anyway)
    unlink(<*.txt>);
    This line alone should do what you want, if the script is run in the directory you want the text files deleted from.
      I know I put the script in the directory below the PERL directory, that way I could open it with the script and then delete the files. Wheres merlyn when ya need him? ;-]

      Well I tried that before but it didn't work...Oh well Ill try it again..

      and i get this... Insecure dependency in unlink while running with -T switch at c:\windows\TEMP\DzTemp.pl line 3
        Your data is tainted :) If you're just trying to delete files, I'd either remove the -T, or use chdir, opendir, readdir, unlink in combo to delete the list of files.
Re: Unlinking...
by chromatic (Archbishop) on Nov 22, 2000 at 03:28 UTC
    I haven't seen anyone explicitly state the problem with that snippet. I'm assuming that "/cgi and perl" is a directory.

    With Perl, you don't open a directory like you would a normal file. Use the opendir command instead. Also, at least on my Unixy machine, that will attempt to read a file in the root directory -- no guarantee what it will do on Windows.

    Obviously, if the directory open fails, reading from the filehandle won't work. So the while line doesn't do anything -- which is good, considering what happens next.

    The unlink line will probably do the trick (depending on how well globbing is implemented in your version of Perl). Unfortunately, it returns a list of all of the files ending in '.txt' in the current directory, which is hardly what you want. You'll either need to chdir to the directory you want to work on, or prepend that directory name to each of the files you want to remove.

    Add the requisite error checking, too. I'd code it with readdir and grep as someone already posted.

Re: Unlinking...
by arturo (Vicar) on Nov 22, 2000 at 02:22 UTC

    Dunno why you've got open in there, the following ought to do what you want

    chdir "/directory/with/files/to/kibosh"; unlink <*.txt>;

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: Unlinking...
by steveAZ98 (Monk) on Nov 22, 2000 at 02:33 UTC
    I'm not quite sure exactly what you want to do, but if you want to delete all the text files in a directory you can do something like this.
    #!/usr/bin/perl -w opendir(DIR, "../test") or die "Can't open ../test: $!"; my @f = readdir DIR; @f = map { unlink $_; $_ } grep { /\.txt$/i } @f;
    or
    my @f = <*.txt>; @f = map { unlink $_; $_ } grep { /\.txt$/i } @f;
    Both of them return the deleted file names in the @f array.
    Update: Or what arturo said above me!
Re: Unlinking... (It worked!...sorta)
by damian1301 (Curate) on Dec 08, 2000 at 23:04 UTC
    Well last night I tried to delete all those darn *.txt files in my cgi and perl directory. And I found out that in my editor that I use to run and code my Perl, that there was a checkbox in the menu that said "Enable Taint checking". As soon as I saw this i was FURIOUS! I lost about 4 XP on that Unlinking... post. Plus, I had to waste all of your time for my ignorance. So I am sorry. After that I unchecked that box and ran the script and sure enough it deleted all the text files that I didn't want, thanks

    Wanna be perl hacker.
    Dave AKA damian
Re: Unlinking...
by djw (Vicar) on Nov 22, 2000 at 18:54 UTC
    Here is a snippet of code that I wrote do some something similar (on win32):

    $create_date = stat($_)->ctime; if ($create_date < ($current_date - $set_time)) { if (unlink ($_)) { open(LOG, ">>$logfile") or warn "discarding logfile output +\n"; print LOG "FIle: $_ - has been deleted.\n"; close (LOG) or warn "Can't close $logfile: $!"; } else { open(ERRLOG, ">>$errorlog") or warn "scrapping error outpu +t\n"; eval { die "($!)"; }; if ($@) { print ERRLOG "Cannot delete file $_ : $@!\n"; } } } else { open(LOG, ">>$logfile2") or warn "discarding logfile output\n" +; print LOG "The file $_ is newer than 30 days.\n"; close(LOG) or warn "Can't close $logfile2: $!"; }
    I am deleting on a creation date test, but you can still view the method. Its a little different than using a direct die statement inside a foreach, but it gets the job done.

    Thanks,
    djw
Re: Unlinking...
by damian1301 (Curate) on Nov 22, 2000 at 02:46 UTC
    I still get the tainting error. I dont have the -T switch on though!

    Insecure dependency in unlink while running with -T switch at c:\windows\TEMP\DzTemp.pl line 6
      If your Perl script doesn't have its first line set with something that ends in, say -T or -wT, I would check your Windows file associations for the .pl extension. It's possible that whatever mechanism you used to install Perl associated all .pl extensions with "perl -T", just to be "safe".