in reply to Unlinking a file when the file doesnt exist

You could simply try to unlink the file even if it does not exist:
for my $file (qw(files.txt data.txt)) { unlink $file; die "Unable to unlink '$file': $!" if -e $file; }

Replies are listed 'Best First'.
Re^2: Unlinking a file when the file doesnt exist
by cdarke (Prior) on Mar 22, 2011 at 17:19 UTC
    A good reason for using this solution is that, in theory at least, you could have a possible race condition with your code. Between check for the existence of the file (-e) and deleting the file another process could have deleted it or even opened it.
      It's not a race condition. It doesn't matter when the file was created or haw many times it was created. The file should be gone and it's not.
Re^2: Unlinking a file when the file doesnt exist
by ikegami (Patriarch) on Mar 22, 2011 at 19:07 UTC

    Unfortunately, $! is garbage in that example. It would only be meaningful if stat (via -e) failed. One definitely cannot count on it having any info about an unlink error.

    I recommend

    for my $file (qw(files.txt data.txt)) { unlink($file) or $!{ENOENT} or die("Unable to unlink '$file': $!"); }

    Or if one wants to clean up as many files as possible even if some can't be deleted,

    my $success = 1; for my $file (qw(files.txt data.txt)) { if (!unlink($file) && !$!{ENOENT}) { warn("Unable to unlink '$file': $!"); $success = 0; } } die("Unable to cleanup") if !$success;
      Unfortunately, $! is garbage in that example.

      It contained the right value when I tried it. Is that platform (or perl version) dependent?

        It may have the right value if you're lucky. stat is free to change it, and you can reach the die even if unlink was successful.

      Unfortunately, $! is garbage in that example.

      From unlink:

      Deletes a list of files. On success, it returns the number of files it successfully deleted. On failure, it returns false and sets $! (errno):

      One of the examples at the perldoc page for unlink shows using $! with warn() in a foreach loop. Why shouldn't $! be used in this case?

        I didn't say anything that contradicts that. It's perfectly fine to use $! immediately after unlink returns an error as I showed in the very post you quoted.

        In moritz's code, $! isn't being used immediately after unlink returns an error. In decreasing likeliness of occurrence,

        • It's sometimes used after stat (-e) successfully returns false. (Can change $!.)
        • It's sometimes used after stat (-e) returns an error. (Always sets $!.)
        • It's sometimes used after unlink returns success. (!!!)
Re^2: Unlinking a file when the file doesnt exist
by Gulliver (Monk) on Mar 22, 2011 at 18:15 UTC

    What if the file is actually a directory? I have never tried it but the documentation for unlink gives some warnings.

    How about:

    for my $file (qw(files.txt data.txt)) { unlink $file if -f $file; die "Unable to unlink '$file': $!" if -e $file; }

    Update: If the file tests are different then it would die after not attempting to delete a directory and $! would not be set. In that case -f is false and -e is true. If I make them the same that won't happen.

    for my $file (qw(files.txt data.txt)) { unlink $file if -f $file; die "Unable to unlink '$file': $!" if -f $file; }

    Better yet; do an unlink or warn.

    for my $file (qw(files.txt data.txt)) { if ( -f $file) { unlink $file or warn "Unable to unlink '$file': $!"; } }