
The perils of file replacement on *nix - r11t
http://www.pixelbeat.org/docs/unix_file_replacement.html
======
jluxenberg
sponge (1) is a simple way to do this, but not available on all systems. See
<http://joey.kitenet.net/code/moreutils/>

~~~
TorKlingberg
This is the most convenient solution. "sponge reads standard input and writes
it out to the specified file. Unlike a shell redirect, sponge soaks up all its
input before opening the output file. This allows for constructing pipelines
that read from and write to the same file."

I remember writing a script that did the same thing (in Perl or maybe it was
Bash).

------
fexl
I use this technique a lot:

    
    
      mv thing thing.old && mv thing.new thing
    

It works whether the thing is a file or a directory; I have an automatic
backup called thing.old; I suppose it's reasonably atomic; and I can do it in
ssh with no worries about losing the network connection in between the two
moves.

~~~
gchpaco
It's not atomic at all although you're unlikely to notice in most situations.
Not what I would use in a script, though.

~~~
fexl
On second thought if you use symlinks I'm pretty sure this is atomic:

    
    
      ln -Tfs $dir $symlink
    

Where $dir is the name of a directory and $symlink is the name of a symlink.

------
zaphar
How many people actually use shell redirection to copy and filter a file?

~~~
orborde
I do it all the time. Is there a better way? I'd love to hear it.

~~~
nathanb
cat filename | filter > newfile

~~~
barrkel
The point is that if filename and newFile are the same file, then this will
overwrite the contents before they are read in by cat.

------
tedunangst
Diagnosis for 2 is wrong. The shell won't be scheduled to truncate the file
after the shell is scheduled to fork/exec cat. The shell is not multithreaded.

~~~
barrkel
The shell doesn't need to be multithreaded to be scheduled; after the fork,
there are multiple processes, not multiple threads. The shell that exec's cat
is in a different process to the one that exec's $filter.

------
nathanb
I don't understand this article. Saying "Replacing the contents of a file on
the UNIX command line using the standard cp/mv commands is surprisingly
tricky" is like saying "driving a car using only your ass is surprisingly
tricky". That's true, but when there are standard, simple, non-tricky ways to
do it then you're really just limiting yourself.

But hey, I'll play along. Won't this work: cp file /dev/stdout > file

~~~
sp332
>I don't understand this article.... cp file /dev/stdout > file

Clearly, since this is point 1 in TFA. file is truncated before it is read,
leaving you with a 0-length file.

