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

Reply via email to