Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
The suggestion about file locking above is pertinent, but perhaps not adequate, because there may be some "loopholes" when trying to lock the file that you're actually editing (see the article cited in the code commentary below).

Better to use a "semaphore" file -- one that has no content itself, but serves only to control access to the file that you intend to edit. A semaphore module that I've used to good effect is included below, together with a snippet to show its usage.

Apart from preventing simultaneous edits on a single file, there are other common sources of "corruption" that you need to watch out for:

  • the disk you're writing on runs out of space before the output file is complete
  • the edit attempt turns out to have no effect -- the input and output are identical, even though they shouldn't be
  • the edit applied by the script turns out to have "unintended" side effects

The first point is just a matter of error checking when writing and closing the file, and/or comparing the input and output file sizes (or the tails of the two files). The second can be solved by running "diff old.file new.file" in a back-tick (qx) operator. The third is rather tricky and application-dependent (good luck with that, if it happens to be an issue for you).

All in all, to be careful, you want to stick with your current basic approach (with file locking and validation added): (a) get a lock on the file, (b) read it and create an edited version of it, (c) validate the edited version, (d) rename the edited version to replace the original, (e) release the lock. As a rule, it's good to keep the duration of the locking to a minimum, but if I understand your task, there's no reducing the five steps mentioned (a-e).

Here's the semaphore-file module that I use in a unix/solaris environment -- haven't tried it on ms-windows yet (update:... now that I think of it, I sort of recall testing this on a couple ms-windows versions (98, 2000)):

package Semfile; use strict; use FileHandle; use Carp; # copied (and documented) by Dave Graff from # The Perl Journal, issue #23 (Vol.6 No.1): # "Resource Locking with Semaphore Files" # by Sean M. Burke. # (removed obsolete url for that article -- see update below) # Create and manage semaphore files, which will guarantee that # simultaneous processes competing for a single resource do not # collide when using that resource. # The semaphore (locked) file has no content -- it is simply the # thing to check, and lock if it's available, before using/altering # the actual shared resource. sub new { my $class = shift(@_); my $filespec = shift(@_) or Carp::croak("What filespec?"); my $fh = new FileHandle; $fh->open( ">$filespec" ) or Carp::croak("Can't open semaphore file $filespec: $!"); chmod 0664, $filespec; # make it ug+rw use Fcntl 'LOCK_EX'; flock $fh, LOCK_EX; return bless {'fh' => $fh}, ref($class) || $class; } sub release { undef $_[0]{'fh'}; } 1; # End of module
And here is how I would normally use it:
use Semfile; ... # All instances of this process (and any other perl process that # uses the same shared resource) will use the same semaphore file: my $lock = Semfile->new( "my_semafore.filename" ); # When that call returns, I have the lock; I'll hold it # till I finish doing sensitive tasks, like: # - read the shared resource # - alter and save the value of that resource # - confirm that I haven't botched it # then: $lock->release;
(Update -- Aug. 8 2005: had to remove the obsolete url, because the TPJ article is not reachable that way anymore. You can still go to and look for "semaphore file Sean Burke" to find the reference. If you subscribe to TPJ (highly recommended), you can read the article.)

(Another update -- Nov. 7, 2006: is gone. Sincere thanks to davebaker for finding that article again:

In reply to Re: Replacing a string in a file by graff
in thread Replacing a string in a file by Avi

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others imbibing at the Monastery: (4)
    As of 2018-06-18 10:37 GMT
    Find Nodes?
      Voting Booth?
      Should cpanminus be part of the standard Perl release?

      Results (109 votes). Check out past polls.