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

Hi Monks In perl, is there anyway to find whether a file is already open or not. Something like this -f : check whether its a file -d : check whether its a directory -e : check whether file exists Regards Sridhar

Replies are listed 'Best First'.
Re: Check whether a file is open
by tirwhan (Abbot) on Jun 02, 2005 at 09:40 UTC
    Not really a Perl answer, but on most Unixes (and Linux) you can use the utility lsof(8). Example:
    lsof /etc/passwd
    Will tell you whether /etc/passwd is currently opened by another process, the pid of that process and a whole lot of other useful stuff.
    lsof +D /etc
    will give you all open files in a directory.
    lsof -p 12345

    will give you all files opened by the process with the pid 12345.

    Apply your favourite variant of backticks or open to examine the output in Perl.

    Hmm, given that there's no Perl wrapper module for lsof in CPAN (and Linux::Fuser is Linux-only), maybe it'd be worthwhile writing one?
Re: Check whether a file is open
by jbrugger (Parson) on Jun 02, 2005 at 09:17 UTC
    You mean by another program?
    As far as i know, you can't.
    But as a workaround, try to open the file exlusive, if it fails, it's probably opened.

    In your own program, try using flock

    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
      To see if it's opened by your own program, use fileno. [Update] Of course, you use fileno on handles rather than on filenames, which is probably not what the OP wants to do. (thanks, tlm)

      Caution: Contents may have been coded under pressure.
Re: Check whether a file is open
by gellyfish (Monsignor) on Jun 02, 2005 at 09:21 UTC

    It depends on what operating system you are on, on Linux for instance you can use Linux::Fuser.

    /J\

Re: Check whether a file is open
by PerlingTheUK (Hermit) on Jun 02, 2005 at 12:13 UTC
    I once did this the "Office" way. Whenever I opened a file for writing I renamed it to "¬".$file or so. If I opened it for reading I would check both filenames. Once editing was finished it got renamed to the old filename again. This surely requires some limitations and a filename was not allowed to use some special characters for a first character.

    Cheers,
    PerlingTheUK
Re: Check whether a file is open
by mikeraz (Friar) on Jun 02, 2005 at 16:11 UTC

    This is one thorny problem. Take, for example, a file arriving via an ftp or scp delivery. The client program may open the file start writing, pause, write some more, operate slowly due to the bandwidth and eventually, maybe sometime finish the transfer. In the meantime your process, running quickly on the local box how no way of knowing whether it is safe to operate on the file.

    Grrrrr there's no cross platform, consistent way to find out if a file is open. If you're in this position, you have to develop some sanity check method(s) to assure yourself the process writing to the file is finished.

    If you're beginning to think I've been bitten by this, you're right. What we eventually did was:

    • grep the output from lsof for the filename in question - this is handy if you're on a Linux system, useless anywhere else
    • once the file doesn't appear in losf compare the atime to NOW. So when  (time - (stat $filename)[8]) > $defined_comfort_level you can proceed under the semi-reasonable illusion that all is fine
    At least the above method has worked for us for over two years now.

    I wish there was a better way. If there is one I'd love to hear about it. If there is a filesysystem that implements something like electricians locks I'd put it on all the systems I'm responsible for.

    Be Appropriate && Follow Your Curiosity
      I wish there was a better way. If there is one I'd love to hear about it. If there is a filesysystem that implements something like electricians locks I'd put it on all the systems I'm responsible for.

      The Reiser4 filesystem implements atomic transactions which can span multiple read/write operations. So your applications can just bunch together operations into a single transaction and not have to worry about what else is accessing the file. You have to use the Reiser-specific system calls though, otherwise it's just atomic to a single operation.

      Of course Reiser4 isn't exactly what you'd call production-ready yet...

      See thread of file locking. Mandatory locking exists (under some systems), but is not a solution.

Re: Check whether a file is open
by ghenry (Vicar) on Jun 02, 2005 at 09:21 UTC

    The only thing I can see is:

    -X

    -t    Filehandle is opened to a tty.

    Not quite the same thing though.

    HTH.

    Walking the road to enlightenment... I found a penguin and a camel on the way.....
    Fancy a yourname@perl.me.uk? Just ask!!!