1 |
Hi list! |
2 |
|
3 |
This is more a general POSIX question but I guess here I have the best |
4 |
chance to get a definite answer. |
5 |
|
6 |
If I want to replace a file with another file without removing the first |
7 |
one and without having a moment in time at which the file name does not |
8 |
exist, I can use the following sequence: |
9 |
|
10 |
# swap $file1 with $file2 on the same file system |
11 |
dir=$(dirname "$file1") |
12 |
tmp=$(mktemp -u -d "$dir") # [1] |
13 |
ln "$file1" "$tmp" |
14 |
mv "$file2" "$file1" |
15 |
mv "$tmp" "$file2" |
16 |
|
17 |
This works because mv does not affect the hardlink to $file1 and a |
18 |
rename operation on a single file system is atomic. This is a handy |
19 |
procedure when you have a background process which occasionally opens |
20 |
$file1 and you don't want it to fail just because of bad timing. |
21 |
|
22 |
Now my question is: How can I do a similar thing for a directory? I |
23 |
cannot usually create hardlinks on directories (are there file systems |
24 |
where this actually works?) and I cannot use mv to overwrite one |
25 |
directory with another. |
26 |
|
27 |
The only idea I currently have is to create a level of indirection via |
28 |
symlinks and then atomically overwrite the symlink. Is there any other way? |
29 |
|
30 |
[1] Yes, I know I need to iterate this and the next line in case a |
31 |
different process creates $tmp in between syscalls. Putting in a few -T |
32 |
and "--" switches might also help but let's keep it simple for the moment. |
33 |
|
34 |
Thanks in advance! |
35 |
Florian Philipp |