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

This script is intended to see if a file in a list is linked toin an HTML file and if the file is not linked to it should be deleted. This works great until I do the unlinking bit. If I just print out the list of files to be deleted it gets it right every time. But this snippet<br
while (@delete_me) { $x = pop(@delete_me); unlink $x or die "Can't unlink $x : $!"; }

produces this errorCan't unlink /home/mysite/www/clean_up/pages/ghost.html : No such file or directory at clean_up.pl line 43.
despite the fact that the path is full and accurate.
Any help?
TIA
jg
#!/usr/local/bin/perl -w use strict; use Fcntl ':flock'; use CGI qw/:standard/; use CGI::Carp qw/fatalsToBrowser /; my $base_path="/home/mysite/www/clean_up"; my $search_terms_file="$base_path/terms.txt"; my $file_to_search="$base_path/searchme.html"; my ($term,$results,@delete_me, $x); do_the_clean_up(); sub do_the_clean_up { open (ST,"$search_terms_file") or die "where's the search_terms fi +le? : $!"; flock (ST,LOCK_EX) or die "Couldn't flock search_terms: $!"; my @search_terms = <ST>; flock(ST,LOCK_UN); close ST or die "search_terms won't close : $!"; chomp (@search_terms); open (FTS,"$file_to_search") or die "where's the file_to_search? : + $!"; flock (FTS,LOCK_EX) or die "Couldn't flock file_to_search.: $!"; my @file = <FTS>; foreach $term(@search_terms) { if ( !grep { /$term/ } @file ) { $term="$base_path$term"; push (@delete_me,$term); } } flock(FTS,LOCK_UN); close FTS or die "Couldn't close file_to_search. : $!"; my @file_list = @delete_me; while (@delete_me) { $x = pop(@delete_me); unlink $x or die "Can't unlink $x : $!"; } print "Content-type: text/html\n\n"; print "<h1>Deleted Files</h1>"; foreach $_(@file_list) { print "$_ <br>"; } exit; }
_____________________________________________________
If it gets a little bit out of hand sometimes, don't let it fool you into thinkin' you don't care.TvZ

Replies are listed 'Best First'.
Re: File Not Found in Attempt To Unlink
by BeernuT (Pilgrim) on Feb 07, 2002 at 02:07 UTC
    this might not be wrong. but it makes more since. Your while statement reads the array in as 0,1,2,3.... But you then set $x = pop(@delete_me); which removes the last element of @delete_me and sets it to $x. Doesnt make to much since to me. so lets rewrite it as.

    foreach (@delete_me) { my $file = $_; unlink $file or die "Can't unlink $file : $!\n"; }

    or you can simple do
    foreach (@delete_me) { unlink $_ or die "Can't unlink $file : $!\n"; }


    -bn
Re: File Not Found in Attempt To Unlink
by jerrygarciuh (Curate) on Feb 07, 2002 at 03:11 UTC
    Hi guys,
    the solution was in unlink. unlink @delete_me; as opposed to
    while (@delete_me) { $x = pop(@delete_me); unlink $x or die "Can't unlink $x : $!"; }

    Thx
    jg
    _____________________________________________________
    If it gets a little bit out of hand sometimes, don't let it fool you into thinkin' you don't care.TvZ
Re: File Not Found in Attempt To Unlink
by jjohn (Beadle) on Feb 07, 2002 at 03:18 UTC

    It's a little hard to see the problem because I don't know your system, but here are a few things to try:

    • Manually check for the file's existence with -e. For example:
      warn "No such path: $x\n" unless -e $x
      This would be placed before the unlink line.
    • This seems to be a CGI script. CGI processes run as the web server's user, which is typically nobody. Can nobody see these files and delete them? su - nobody to check this.
    • You code doesn't grep through the actual files, but instead looks through one data file. The mistake may be that the paths in that file are fubar.
    • There's no need to read in FTS file. This is a waste of memory. Also your search terms don't change, so you can be a little trickier with the regex. Consider something like this:
      my $pattern = join '|', map{"\Q$_\E"}@search_terms; while(my $suspect = <FTS>){ chomp($suspect); if( $suspect =~ /$pattern/o ){ push @delete_me, "$base_path$term"; } }
      This creates an regex pattern that is an alternation of all your search terms, each of which has potential regex meta characters escaped. Of course, this may not be want you want if the search terms are regex patterns themselves. In that case, remove the map clause.
    • It strikes me as odd that your search terms appear to be filenames. This is intentional?
    • If you're going to use $_, enjoy the saved characters:
      foreach (@file_list){ # don't bother putting $_ here print $_, '<br>'; }

    Hopefully in some of this message, you'll find the key to unlocking this thorny problem. Good luck!

    --jjohn