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).
pipefailoption on as 141 would be the exit status ofyes, notmvwhich would have no reason to get a SIGPIPE here. – Stéphane Chazelas Dec 10 '15 at 13:05-Tfor that. – Stéphane Chazelas Dec 10 '15 at 13:14mvrather than that ofyes, the simplest solution might bemv -i file1 file2 < <(yes n)– kasperd Dec 11 '15 at 10:02