What is the point of mv -f when default behavior already overwrites files?

23,498

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.

Share:
23,498

Related videos on Youtube

Jesse Nickles
Author by

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, 2022

Comments

  • Jesse Nickles
    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 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?

    • Wildcard
      Wildcard over 8 years
      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.
    • PlasmaHH
      PlasmaHH over 8 years
      Equivalent behaviour can not be used if MV is alised to mv-i
    • user2071406
      user2071406 over 8 years
      IMO, it's also nice for use in scripts, because you're being explicit. It communicates intention a little better.
  • Admin
    Admin over 8 years
    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.
  • Admin
    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
    vonbrand over 8 years
    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...
  • choroba
    choroba over 8 years
    @sampablokuper: updated.
  • Admin
    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
    choroba over 8 years
    @sampablokuper: They all use mv -i. If you want to use them but skip the interaction, you'd use MV -f etc.
  • Admin
    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 just mv)?
  • choroba
    choroba over 8 years
    @sampablokuper: No, because the user wants to skip the interaction, not the logging or whatever else.
  • Admin
    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
    choroba over 8 years
    @sampablokuper: Just imagine something like echo $(date) $USER moving "@$" >> /some/log before the mv line.
  • Alexander
    Alexander over 8 years
    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.
  • Walter
    Walter over 8 years
    You may think overriding -i is unlikely, but that is exactly why I would guess that -f is used like that.
  • DSpencer
    DSpencer over 8 years
    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.
  • Eric Leschinski
    Eric Leschinski over 7 years
    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.
  • phk
    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 between mv -f and \mv.
  • phk
    phk about 7 years
    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
    phk about 7 years
    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.