Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Is the file there?

by Ahbeyra (Monk)
on Oct 25, 2001 at 05:56 UTC ( [id://121343]=perlquestion: print w/replies, xml ) Need Help??

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

How can you test if a file exists in a directory and if it does, kill the cgi script, or give an error message or warning?

---------------------------------
I love the smell of pastures in the morning... /tell ahbeyra moo

Replies are listed 'Best First'.
Re: Is the file there?
by BMaximus (Chaplain) on Oct 25, 2001 at 13:29 UTC
    I feel the need to explain why I gave this question a --.

    While I'm very tolerant of very short and simple questions and always think that lazyness is a good quality of a programmer. I also feel that a monk should do his/her homework before asking a question (as we constantly and gently remind others to do a Super Search first before asking questions). This is something that I have learned from PM. Understandably Ahbeyra may be a novice but looking at his (her?) previous questions and writeups and given the resources that PM has. Even without the Camel book he (she?) should have been able to come up with a solution.

    I hope I'm not being too harsh. If so -- away on me. I just think Ahbeyra would have learned more if we had nudged him (her?) in the right direction to figure this out himself (herself?). I know I enjoy it more when I figure things out for myself. I remember when I had played a game called The Stone. Its basicaly a puzzle site with a comunity very much like ours. If someone had a hard time with a puzzle instead of receiving the answer outright, they would get a nudge in the right direction to find it themselves. Don't we all at PM strive to not only learn here but to also be the teacher?

    BMaximus

    sorry Ahbeyra, I can't figure your gender from your name
      A) Im male, B) Why would i give you --'s for stating your opinion?, C) i checked around, i even looked at other sites, i just didnt find anything that looked like it had to do with what i wanted.

      ----------------------------------
      I love the smell of pastures in the morning... /tell ahbeyra moo
      I have some sympathy with this view, but I think it depends on the question. If it's something that is a bit obscure, but which one really ought to be able to figure out, then one should figure it out and keep quiet. But in the present case, this is a question that almost everyone is going to have to deal with in some form or other. In that case, the thread itself can become a very useful learning resource. I find I learn a lot from the dialectic between the different solutions - a dialectic which was very healthy in this thread. As well as presenting a lot of good information, it also presents it in a way that engages one's critical attention, so that one retains the knowledge far better than by reading the same stuff in a book.

      So I think there's a place for this kind of thread. It does no harm to go over the basic stuff - often one can learn something unexpected from doing so. And for some of us it's not all that basic!

      (For the avoidance of doubt I haven't voted anyone down on this thread - I thought it was all good stuff. A healthy dialectic, as I say.)

      § George Sherston
Re: Is the file there?
by higle (Chaplain) on Oct 25, 2001 at 06:07 UTC
    ... opendir(FOO, "/bar/baz"); my @files = readdir FOO; closedir FOO; foreach my $file (@files){ chomp $file; die $predefined_die_msg if $file =~ /^file_name$/i; } ...
    Make sure that, before outputting any error messages to the browser, you print an HTML header. The die/warn message will be printed to the browser if this is going to be run as a CGI.

    Update: Even though this is the most IO-intensive 'solution' to the problem, and definitely the longest to execute, it still works, in a caveman kinda way. :) Added line start/line end boundaries to the regex, and chomped that thang.
    #------------- perl -e 's=$;$/=$\;W=i;$\=$/;s;;XYW\\U$"\;\);sig,$_^=$[x5,print;'
      I think you'd better anchor that regex or else your /file_name/ will match a file called "this_is_a_file_named_Joe" (that is to say use /^file_name$/). Even better would be to use eq in this case (with suitable use of lc if you are using a case-insensitive file system).

      A larger problem is that the directory contents could well have changed between the readdir and the testing loop, so your result won't be certain. Since you are going to die when you find a match anyway, you could just as well put the readdir in the loop condition and not bother with the array at all, which makes your test somewhat more reliable. Even so, you're still testing whether a variable (the return value of the readdir) matches a string, which does not really tell you anything certain about a file on disk.

      The best solution would be to use the file test operator: die $message if -f '/ber/baz/file_name'.

      Update: A fair point Tyke. Of course -e also returns true for a directory, for which one might want to be more specific using -d if one were actually looking for a directory. We don't know the greater purpose of the test in this case, but perldoc -f -X should certainly be consulted to select the best test available under the circumstances.

      --
      I'd like to be able to assign to an luser

        -f tests if the file is a 'plain' file or not. If you want to test for existence you might be better off with the -e test
      Thanks! lots of thanks actually, as simple as that is, i couldnt get it to work ;)

      ----------------------------------
      I love the smell of pastures in the morning... /tell ahbeyra moo
Re: Is the file there?
by Zaxo (Archbishop) on Oct 25, 2001 at 06:28 UTC

    In cgi scripts, you need to worry about more than one instance running at a time. That requires locking, as well as the exclusivity you want:

    my $path = "$dir/$name"; my $fh; use Fcntl; sysopen ( $fh, $path, O_WRONLY|O_EXCL|O_CREAT|O_EXLOCK ) or die $!;
    Update: Explicitly added Fcntl to get the symbols defined. Ahbeyra, please say what error messages you get, maybe post some more code.

    Update2: Added O_CREAT flag. Props to jeroenes for spotting.

    After Compline,
    Zaxo

      When i do that, it dies regardless... is there something i could be doing wrong to causing it?

      -----------------------------
      I love the smell of pastures in the morning... /tell ahbeyra moo
        A small wonder, if the file you try to open isn't there. The file can't be opened, and the die part is executed. Check out Albannach's post, and learn about the file test operator: -f $file.
Re: Is the file there?
by MZSanford (Curate) on Oct 25, 2001 at 13:27 UTC
    not to keep it too simple, maybe :
    if (-e $file_with_path) { # die here }

    Albannach also mentioned this.
    i had a memory leak once, and it ruined my favorite shirt.
Re: Is the file there?
by staeryatz (Monk) on Oct 25, 2001 at 08:10 UTC
    Try this:
    ...
    
    open(TESTFILEHANDLE, "<$yourfilename") && die "$!, $yourfilename already exists.\n";
    
    ...
    
    The && die... will kill the program and display the message, IF AND ONLY IF, the file was successfully opened (readonly), which in your case, is what you wanted. You can also replace the "die" keyword with "warn" if you don't want to kill the program.

    Of course, it's a good example to close the filehandle before exiting the program.

    I hope it helps.

Re: Is the file there?
by graq (Curate) on Oct 25, 2001 at 12:19 UTC
    There seems to to be a few answers that do a little more than you asked in your original question.
    So I'll try to help with a more minimalist answer (offering my share of TIMTOWTDI):
    #!/usr/bin/perl -w use strict; my $file = $ARGV[0]||__FILE__; print "WARNING: $file exists\n" if( -e $file );

    <a href="http://www.graq.co.uk">Graq</a>

Re: Is the file there?
by strfry() (Monk) on Oct 25, 2001 at 21:29 UTC
    here's my TMTOWTDI
    #!/usr/bin/perl use strict; use warnings; # change to -w for < 5.6 (i think) my $file = "$ENV{'HOME'}/.poof"; if(stat($file)) { print "we were able to stat $file\n"; } else { die "$!\n"; # or warn() ... }


    -- strfry()
    <code nowrap> perl -e '$;=qq.rekcalsxlrePxrehtonaxtsuJ.;$;=~s>x>qq|\x20|>eg;$_=qq.\x0a.;print scalar reverse$;;END{print};'</code>

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (7)
As of 2024-04-23 10:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found