A race-free approach with GNU ln
provided file1
is not of type directory:
ln -PT file1 file2 && rm file1
(Except for bugs in some network file systems), that guarantees that no file2
file will get overridden (or that if file2
is of type directory, file1
will not be moved into it), because the link()
system call, contrary to the rename()
system call will fail if the target exists.
However, there will be an intermediate state where the file exists both as file1
and file2
.
The -T
option (to always do a link("file1", "file2")
even if file2
is of type directory) is GNU-specific.
You could also use the link
command:
link file1 file2 && rm file1
However, if file1
is a symlink, depending on the implementation, file2
will be either a hardlink to that symlink or to the target of that symlink (on Solaris, use /usr/sbin/link
, not /usr/xpg4/bin/link
).
pipefail
option on as 141 would be the exit status ofyes
, notmv
which would have no reason to get a SIGPIPE here.-T
for that.mv
rather than that ofyes
, the simplest solution might bemv -i file1 file2 < <(yes n)