On 08/07/2026 13:51, Florian Weimer via GNU coreutils Bug Reports wrote:
* Florian Weimer via:
Based on the documentation, I would have expected an error in this case.
mkdir a a/1 b b/2
mv -Tn a b
Exit status is zero. The only relevant system call in the strace output
is this one:
renameat2(AT_FDCWD, "a", AT_FDCWD, "b", RENAME_NOREPLACE) = -1 EEXIST (File
exists)
Right the documentation got out of sync a bit.
We changed the behavior to exiting with failure in:
https://github.com/coreutils/coreutils/commit/7a69df889
Though there was push back on that due to scripts breaking,
so it was reverted in:
https://github.com/coreutils/coreutils/commit/9907b6f5d
However I failed to update the mv -n info docs accordingly.
In some quick testing here I see mv -n silently fails on solaris,
but (like Linux) silently skips on FreeBSD.
So we should deprecate (non POSIX) -n for mv as we've
already done for cp.
I'll push the attached to address this documentation issue.
Seen with: coreutils-9.7-9.fc43.x86_64
I see that there is a hint in the -n description that the exit status
may not be what users expects. But it means that this claim in the
manual is slightly misleading:
| However, if ‘mv -T /tmp/source /tmp/dest’ succeeds, there is no
| question that ‘/tmp/source’ was renamed to ‘/tmp/dest’.
The above is OK I think, as it doesn't mention -n.
Marking this as done.
thanks,
Padraig
From 53926ba7d87e298ba8361681d29f6fefd256b082 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Wed, 8 Jul 2026 18:55:34 +0100
Subject: [PATCH] doc: fix description of mv -n
The description of mv --no-clobber got out of sync
between commit v9.1-133-g7a69df889 and v9.4-134-g9907b6f5d
* doc/coreutils.texi (mv invocation): Copy most of the -n
description from the cp --no-clobber description.
* src/mv.c (usage): Likewise. Note this explicitly deprectates
the mv -n option as like cp the exit code varies across platforms.
Solaris 11 was seen to silently fail, while Linux/FreeBSD succeed.
Fixes https://bugs.gnu.org/81377
---
doc/coreutils.texi | 24 ++++++++++++++----------
src/mv.c | 2 +-
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 29baf5710..d3e3723c1 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -8875,15 +8875,24 @@ to cause @command{cp} write to arbitrary target directories.
@optItemx{cp,--link,}
Make hard links instead of copies of non-directories.
-@optItem{cp,-n,}
-@optItemx{cp,--no-clobber,}
+@macro noClobberOption{cmd}
+@optItem{\cmd\,-n,}
+@optItemx{\cmd\,--no-clobber,}
+@cindex prompts, omitting
Do not overwrite an existing file; silently skip instead.
+@ifset MV_COMMAND
+@mvOptsIfn
+@end ifset
+@ifclear MV_COMMAND
This option overrides a previous @option{-i} option.
+@end ifclear
This option is mutually exclusive with @option{-b} or @option{--backup} option.
This option is deprecated due to having a different exit status from
other platforms. See also the @option{--update} option which will
give more control over how to deal with existing files in the destination,
and over the exit status in particular.
+@end macro
+@noClobberOption{cp}
@optItem{cp,-p,}
@optItemx{cp,--preserve,[=@var{attribute_list}]}
@@ -10015,14 +10024,9 @@ Prompt whether to overwrite each existing destination file, regardless
of its permissions, and fail if the response is not affirmative.
@mvOptsIfn
-@optItem{mv,-n,}
-@optItemx{mv,--no-clobber,}
-@cindex prompts, omitting
-Do not overwrite an existing file; silently fail instead.
-@mvOptsIfn
-This option is mutually exclusive with @option{-b} or @option{--backup} option.
-See also the @option{--update=none} option which will
-skip existing files but not fail.
+@set MV_COMMAND
+@noClobberOption{mv}
+@clear MV_COMMAND
@optItem{mv,--no-copy,}
@cindex renaming files without copying them
diff --git a/src/mv.c b/src/mv.c
index cd6aab473..3ba6f701e 100644
--- a/src/mv.c
+++ b/src/mv.c
@@ -288,7 +288,7 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\
"));
oputs (_("\
-n, --no-clobber\n\
- do not overwrite an existing file\n\
+ (deprecated) silently skip existing files. See also --update\n\
"));
fputs (_("\
If you specify more than one of -i, -f, -n, only the final one takes effect.\n\
--
2.55.0