49

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 override alias 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 using mv, which is much more concise and comprehensible than using mv -if.

That being the case, what is the purpose of the -f flag? Why does it exist?

3
  • 7
    Defaults 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.
    – Wildcard
    Commented Oct 16, 2015 at 14:46
  • Equivalent behaviour can not be used if MV is alised to mv-i
    – PlasmaHH
    Commented Oct 16, 2015 at 16:23
  • 1
    IMO, it's also nice for use in scripts, because you're being explicit. It communicates intention a little better. Commented Oct 18, 2015 at 20:00

5 Answers 5

49

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).

2
  • Great 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.
    – user6860
    Commented Oct 19, 2015 at 12:26
  • It'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
    Commented Mar 18, 2017 at 14:23
17

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.

4
  • 2
    Thanks, 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.
    – user6860
    Commented Oct 16, 2015 at 14:30
  • 12
    I 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...
    – vonbrand
    Commented Oct 16, 2015 at 14:33
  • 1
    vonbrand, 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 by mv, at one point or another.
    – Alexander
    Commented Oct 16, 2015 at 17:04
  • 1
    You may think overriding -i is unlikely, but that is exactly why I would guess that -f is used like that.
    – Walter
    Commented Oct 18, 2015 at 5:55
11

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).

9
  • @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?
    – user6860
    Commented Oct 16, 2015 at 14:31
  • @sampablokuper: updated.
    – choroba
    Commented Oct 16, 2015 at 14:37
  • @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!
    – user6860
    Commented Oct 16, 2015 at 14:47
  • @sampablokuper: They all use mv -i. If you want to use them but skip the interaction, you'd use MV -f etc.
    – choroba
    Commented Oct 16, 2015 at 14:49
  • 1
    @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 between mv -f and \mv.
    – phk
    Commented Mar 18, 2017 at 14:21
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.

-1

In shell programming, using -f is a common idiom used to make sure that your commands don't abort with errors or ask the script/user for interactive response when running certain commands. The last thing you want is for your script to pause waiting for user input, or perhaps worse, for the wrong command to take the input from standard in.

Note: undoing an alias can cause/remove side effects. If you have aliased the command to another version or with additional options, undoing the alias will cause unwanted side effects. For example, you might have alias setup with mv and rm to use a recycle can (or other protection/tracking systems). Undoing the alias will break this...

2
  • Nitpick: 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. Commented Oct 27, 2016 at 20:23
  • Two 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 because mv -i -f differs from mv, see Mark's answer.
    – phk
    Commented Mar 18, 2017 at 14:29

You must log in to answer this question.