What is the point of mv -f when default behavior already overwrites files?
Solution 1
The usage of -f
is more clearly described in the man page from 4BSD, which was where the -f
and -i
options were added:
If file2 already exists, it is removed before file1 is moved. If file2 has a mode which forbids writing, mv prints the mode and reads the standard input to obtain a line; if the line begins with y, the move takes place; if not, mv exits.
Options:
-i
stands for interactive mode. Whenever a move is to supercede an existing file, the user is prompted by the name of the file followed by a question mark. If he answers with a line starting with 'y', the move continues. Any other reply prevents the move from occurring.
-f
stands for force. This option overrides any mode restrictions or the-i
switch.
An even more precise definition of how mv operates is given in the POSIX standard, which adds that -f
only overrides -i
if it occurs later in the command line.
So the default behavior is a bit different from -f
. The default is to ask for confirmation only when the target isn't writable. (This behavior goes back at least as far as V4, where mv
didn't take any options.) If the -i
option is given, mv will additionally ask for confirmation whenever the target exists. The -f
option will inhibit asking in both of those cases (if it occurs after any -i
).
Solution 2
It's useful when having set the execution of mv
to a sane default:
alias mv="mv -i"
When you then want to force a move, this will work:
mv -f
Since it's the last option in the expanded command that counts:
mv -i -f
This point is also mentioned in the GNU Coreutils manual.
Solution 3
It exists because (man mv
)
If you specify more than one of
-i
,-f
,-n
, only the final one takes effect.
So, you can have a script/alias/function that always asks, but you can still override the option.
# alias
alias mv='mv -i'
# function
MV () { mv -i "$@" ; }
# script
#!/bin/bash
mv -i "$@"
A meaningful function/script would do something more, of course (e.g. log the action).
Solution 4
The mv
command on its own can function differently with the -f
option, in that it will try to overwrite write protected files without a prompt.
user2@host:location> ls -l ./
drwxrwxr-x 2 user1 users 10 Oct 16 12:58 dir
user2@host:location> ls -l ./dir/
-rw-r--r-- 2 user1 users 0 Oct 16 12:58 file1
-rw-r--r-- 2 user2 users 0 Oct 16 12:58 file2
user2@host:location> \mv ./dir/file2 ./dir/file1
'mv' try to overwrite './dir/file1', overridding mode 0644 (rw-r--r--)? n
user2@host:location> \mv -f ./dir/file2 ./dir/file1
user2@host:location> ls -l ./dir/
-rw-r--r-- 2 user2 users 0 Oct 16 12:58 file1
Because of write permissions in the directory user2 can overwrite user1 files in ./dir/
, but will be warned before doing so. -f
prevents the warning.
Related videos on Youtube
Jesse Nickles
I'm passionate about free speech, FOSS, and the open web, and my company LittleBizzy maintains several free WordPress plugins being used by organizations like United Nations, Emirates Airlines, and Flipkart. I also maintain SlickStack on GitHub, an open-source Bash script for deploying LEMP stack servers on Ubuntu with an emphasis on technical SEO. If you want market-leading performance and security for your WordPress websites without the headache of Docker containers (or having to pay for overpriced "premium" web hosting services), consider checking it out and getting involved. Contact me: https://jessenickles.com/contact
Updated on September 18, 2022Comments
-
Jesse Nickles over 1 year
The GNU Coreutils manual for
mv
says:-f --force Do not prompt the user before removing a destination file.
However, this already seems to be the default behaviour for
mv
, so the-f
option appears to be superfluous. E.g. in GNU Bash version 4.3.11:$ ls -l total 0 $ touch 1 2; mv -f 1 2; ls 2 $ touch 1 2; mv 1 2; ls 2
It seems unlikely the intention of the
-f
flag is to overridealias mv="mv -i"
, because there are several standard ways of overriding an alias (e.g. using\mv
) that would do this more concisely and in a way that is consistent across commands.The manual notes that, "If you specify more than one of the -i, -f, -n options, only the final one takes effect," but it still seems unlikely the intention of the
-f
flag is to override the-i
flag in general, because equivalent behaviour can be achieved by simply usingmv
, which is much more concise and comprehensible than usingmv -if
.That being the case, what is the purpose of the
-f
flag? Why does it exist?-
Wildcard over 8 yearsDefaults are a finicky business. Take a tool such as
mount
, for instance (though there are better examples). Do you really want to have to remember what the defaults are for every option, so you can determine which options you need to set? It's a GOOD THING to have options both for the default and the non-default, so you can explicitly set the option instead of needing to mentally keep track of what the default is. Something there is easier to remember than something not there. -
PlasmaHH over 8 yearsEquivalent behaviour can not be used if MV is alised to mv-i
-
user2071406 over 8 yearsIMO, it's also nice for use in scripts, because you're being explicit. It communicates intention a little better.
-
-
Admin over 8 yearsThanks, but for reasons I've now added to the question, it seems unlikely that overriding
alias mv="mv -i"
is the reason for the existence of-f
. -
Admin over 8 years@choroba Thanks, but for reasons I've now added to the question, it seems unlikely that overriding aliases such as
alias mv="mv -i"
is the reason for the existence of-f
. You mention scripts and functions as well, though. Please could you give examples using these two? -
vonbrand over 8 yearsI object to calling the default "do as you are asked, no dumb questions" behaviour of
mv(1)
(and other Unix commands) "insane" as you imply... -
choroba over 8 years@sampablokuper: updated.
-
Admin over 8 years@choroba, thanks again. Sadly, neither your function example nor your script example uses
mv -f
, so it's still unclear to me how they justify/explain its existence. Sorry if I'm missing the obvious! -
choroba over 8 years@sampablokuper: They all use
mv -i
. If you want to use them but skip the interaction, you'd useMV -f
etc. -
Admin over 8 years@choroba, sure, but I still don't see how
-f
adds value in those examples. To skip the interaction, couldn't the user equally well (and more concisely/clearly) use\mv
(or even justmv
)? -
choroba over 8 years@sampablokuper: No, because the user wants to skip the interaction, not the logging or whatever else.
-
Admin over 8 years@choroba, Would you mind expanding your function and script to illustrate the
-f
flag actually adding value (e.g. in the sort of manner you've just described)? It would be great to have concrete examples. Thanks! -
choroba over 8 years@sampablokuper: Just imagine something like
echo $(date) $USER moving "@$" >> /some/log
before themv
line. -
Alexander over 8 yearsvonbrand, while I appreciate the direct response of Linux/UNIX commands without
-i
, I believe that anyone who has used the command line for more than a few years has been burned bymv
, at one point or another. -
Walter over 8 yearsYou may think overriding -i is unlikely, but that is exactly why I would guess that -f is used like that.
-
DSpencer over 8 yearsGreat answer, thanks! N.B. Some file systems (e.g. CIFS) may cause mv to exhibit unexpected behaviour (i.e. different to the manual), such as acting as though the
-f
flag had been used even if it had not been used. -
Eric Leschinski over 7 yearsNitpick: The
-f
option for cp or mv does not guarantee that "they work". For example if the permission is insufficient, the -f command will not make it work. What you meant to mean is that -f forces an overwrite without prompt. The opposite flag -i means require interactive on overwrite. -
phk about 7 years@sampablokuper The behavior of
mv
without any of those options is to sometimes ask (target not writable and interactive terminal), so this would be a clear difference betweenmv -f
and\mv
. -
phk about 7 yearsIt's worth noting that many implementations only ask for confirmation if they appear to be in an interactive terminal (
isatty(0)
). Also, while it's true that a later-f
overrides-i
, it might not mean that this is the same as no arguments given. -
phk about 7 yearsTwo things to note: 1.) Implementations would normally test for whether you are even in an interactive terminal (
isatty(0)
), so e.g. if your script runs as part of a pipe it won't get triggered. 2.) Adding-f
is not the same as undoing-i
becausemv -i -f
differs frommv
, see Mark's answer.