mv
mv moves files and directories from one place to another. Moving a file within the same directory, under a new name, is how you rename it.
mv [options] source dest
mv [options] source... directory
mv [options] -t directory source...
$ mv draft.txt report.txt # rename
$ mv report.txt notes.txt /home/jack/done/ # move into a directory
A move is either a rename or a copy-and-delete #
mv does its job in one of two ways, and which one decides what happens to the file's security.
Within one file system, a move is normally a rename. Nothing is copied: the file stays exactly where it physically is, and only its name and directory entry change. The file keeps its inode, and so it keeps its security descriptor unchanged — its owner, access rules, and audit rules stay the same. A rename does not re-evaluate inheritance; a file does not pick up new rules just because it landed in a new directory.
Across file systems, a move is a copy followed by a delete. When the destination is on a different file system, mv cannot just rename — it copies the data to a new file on the destination, then removes the original. That new file is a genuinely new object, so, exactly as with cp, it gets a fresh security descriptor inherited from the destination directory unless you ask otherwise.
So: rename a file and its security is untouched; move it to another file system and the copy starts fresh.
The same applies to POSIX ownership: the copy is a new file owned by whoever ran mv, and the source's uid and gid are not carried. Because of that, a cross-file-system move also drops the setuid and setgid bits from the copy, as GNU mv does: a set-id file that changed hands would grant the mover's identity, not the original owner's. Data, timestamps and ordinary extended attributes do travel with the file.
When a directory is moved across file systems onto an existing destination, mv removes the destination and recreates it. If something else appears under that name in between, mv refuses with "destination was replaced while moving" rather than copying into it.
Selecting attributes forces a copy-and-delete #
mv accepts the same attribute-selection options as cp: --preserve, --no-preserve, --preserve-all, --sd, and --sd-explicit. Specifying any of these options forces a copy followed by deletion of the source, even within one file system, rather than a rename. The selected options control which attributes are carried onto the new file.
See cp attribute selection and security preservation for the attribute list and the meaning of these options.
Overwriting an existing destination #
By default mv overwrites an existing destination. These options change that. When more than one of -i, -f, -n is given, the last one wins.
| Option | Effect |
|---|---|
-i, --interactive | Ask before overwriting an existing file. |
-f, --force | Do not prompt before overwriting. |
-n, --no-clobber | Never overwrite an existing file. |
-u, --update[=WHICH] | Select the update policy below. -u and bare --update select older. |
-b, --backup[=CONTROL] | Make a backup of the destination before overwriting it. |
The update modes are:
all: no age restriction; this is the default when no update option is given. Other overwrite options still apply.older: move when the destination is missing or the source is newer; otherwise skip successfully.none: skip existing destinations successfully.none-fail: refuse to replace an existing destination and report failure.
A backup is refused when making it would destroy the source: if the source is the file the destination's backup would be written over (for example mv --backup=simple a~ a), mv stops with an error. The check compares file identity, not how the paths are spelled.
Other options #
| Option | Effect |
|---|---|
-t, --target-directory=DIR | Move every source into DIR. |
-T, --no-target-directory | Treat dest as a plain file even if it is a directory. |
--strip-trailing-slashes | Strip any trailing slashes from each source argument. |
-v, --verbose | Print each file as it is moved. |
--debug | Explain in detail how each file was moved. Implies -v. |
--progress | Show a progress bar. |
Exit status #
| Code | Meaning |
|---|---|
0 | No error was reported. This includes successful skips; it does not mean every source was moved. |
1 | A move failed, including refusal to replace an existing destination with --update=none-fail. |