7 ms·
The perils of file replacement on *nix
- zaphar 17y agoHow many people actually use shell redirection to copy and filter a file?
- jluxenberg 17y agosponge (1) is a simple way to do this, but not available on all systems. See http://joey.kitenet.net/code/moreutils/ http://joey.kitenet.net/code/moreutils/
- LlamaZorz 16y agoThanks for this.
- TorKlingberg 17y agoThis 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).
- nathanb 17y agoI 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 17y ago>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.
- fexl 17y agoI 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 17y agoIt's not atomic at all although you're unlikely to notice in most situations. Not what I would use in a script, though.
- fexl 17y agoRight ... "reasonably atomic" I say. Come to think of it, I'm not sure what I'd use in a script for this.
- deleted 17y ago[deleted]
- fexl 17y agoOn 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.
- tedunangst 17y agoDiagnosis 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 17y agoThe 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.