Linux command: mv
Moving a file feels even simpler than copying one. You type mv, the old name, the new name, and press Enter. Nothing seems to happen, and that is the whole surprise: on the same disk, mv does not move a single byte of your data. It changes a name in a list and finishes instantly, whether the file is two kilobytes or two hundred gigabytes. The same command also renames files, quietly overwrites whatever was in its way, and has no undo. Learning mv properly means learning what a filename really is in Linux.
1. The Basics
The job of mv is to move a file, which in practice means one of two things: give a file a new name in the same place, or move it to a different place. Both are the same operation to mv. When you rename draft.txt to final.txt, and when you move final.txt into another folder, you are doing exactly one thing under the hood: changing where a name points.
That is the mental model worth holding on to. A file's data lives on the disk, and its name lives in a directory as a small entry pointing at that data. Within one filesystem, mv only edits directory entries; it never touches the data itself. This is why moving a huge file on the same disk is instant, while copying that same file with cp takes real time and real space. A move rearranges names; a copy duplicates bytes.
The command reads left to right: the last argument is the destination, and everything before it is a source.
$ mv draft.txt final.txt
The command that looks like it does nothing, because on the same filesystem it barely does. Behind those two letters sits one of the cleanest ideas in Unix: a name and its data are separate things, and moving a file is just moving the name.
This article starts with the simplest rename and builds up to moving whole directory trees without a recursive flag, making backups instead of overwriting, the atomic rename that makes mv the safe way to update a file, and why a move across two disks is far more dangerous than a move on one. By the end you will know not only how to move a file, but exactly when mv is about to destroy one.
Back to topThe right mental model: within one filesystem,
mvdoes not move data, it moves a name. The original data never leaves its spot on the disk; only the label that points to it changes.
2. Where the Name Comes From
The name mv is simply short for move. As with most early Unix commands, there is no hidden meaning; the two letters are the first and last consonants of the word.
mv = MoVe
Early Unix was typed on slow teletype terminals that printed every character onto paper, so short command names saved both typing and ink. That is why the command is mv and not move. The same instinct gave us cp (copy), rm (remove), and ls (list): a whole vocabulary of two-letter verbs.
One small point of confusion is that mv also renames files, yet there is no separate rename command for the everyday case; renaming is just moving a file to a new name in the same directory. The manual page even spells this out in its title: "move (rename) files". If you ever move to Windows, note that its shell splits the job into move and rename; Unix treats them as one.
3. A Short History
The mv command is one of the original Unix tools. It shipped in Unix 1st Edition at Bell Labs in 1971, alongside cp, cat, and rm, and it has been present on every Unix-like system since: Linux, macOS, the BSDs, Solaris, and AIX. The core idea, "change where a name points", has not changed in over fifty years.
What makes mv special is the system call underneath it. On the same filesystem, mv uses rename(), a single kernel operation that swaps a name from one place to another in one indivisible step. Nothing is copied, and there is no in-between state where the file exists in both places or neither. When the source and destination sit on different filesystems, rename() cannot work, so mv falls back to the slow path: copy every byte to the new location, then delete the original.
| Era | Milestone |
|---|---|
| 1971 | mv ships in Unix 1st Edition at Bell Labs |
| 1980s | BSD and System V refine cross-filesystem moves (copy-then-delete) |
| 1990s | GNU coreutils mv becomes the standard version on Linux |
| 2009 | GNU mv gains -u (update) and a proper --backup family |
| 2023 | coreutils 9.x adds --no-copy and an --update= mode selector |
There are two families you will meet in practice. Most Linux systems run the GNU coreutils version of mv. macOS and the BSDs ship the BSD version. They agree on the everyday flags such as -i, -f, and -v. The differences are in the extras: GNU adds long options (for example --backup, --strip-trailing-slashes, and --update) that BSD either spells differently or lacks. This article uses the GNU version, which is what you will find on almost every Linux server.
4. Simple Use Cases
4.1 Renaming a File
Give mv a source and a new name, and it renames the file. In the examples below, the line that starts with $ is what you type; a command that prints nothing simply succeeded, which is the normal Unix way of saying "all good".
$ mv notes.txt notes-final.txt
$ ls
notes-final.txt
Notice that the original name is gone. Unlike cp, which leaves you with two files, mv leaves you with one: the same file under a new label.
4.2 Moving a File Into a Directory
If the destination is an existing directory, mv puts the file inside it and keeps the original filename. This is the most common everyday use: filing something away into a folder.
$ mv report.txt /home/peter/archive/
$ ls /home/peter/archive/
report.txt
The trailing slash on archive/ is a good habit: it makes your intent clear and, if you mistype the folder name, mv fails loudly instead of quietly renaming report.txt to a file called archive.
4.3 Moving Several Files at Once
When you give more than two arguments, mv treats the last one as a destination directory and moves every file before it into that directory. This is where the "last argument is the destination" rule really matters.
$ mv index.html style.css script.js /var/www/site/
All three files land in /var/www/site/. If that last argument is not an existing directory, mv refuses and prints an error, which is a helpful safety net:
$ mv a.txt b.txt nodir
mv: target 'nodir': No such file or directory
4.4 Moving a Directory: No -r Needed
Here is the first real difference from cp. To copy a directory you must add -r, because copying a folder means duplicating everything inside it. Moving a directory needs no such flag. Because a move on the same filesystem only changes one name, moving a folder of ten thousand files is exactly as instant as moving one file.
$ mv project /home/peter/projects/
$ ls /home/peter/projects/
project
The whole tree comes along, instantly, because nothing inside it actually moved. Only the directory's own entry changed to point at a new parent. That single fact explains most of what makes mv feel almost magically fast.
Back to topRenaming a file and moving a file are the same operation. Whether the destination is a name or a directory, and whether it already exists, quietly changes where your file ends up. Section 6 returns to that trap.
5. Moderate Use Cases
5.1 Not Overwriting Silently: -i and -n
By default mv overwrites an existing destination file without warning. If final.txt already holds something important, a careless move wipes it out and the file it replaced is gone for good. Two flags make mv more careful.
The -i flag (short for interactive) asks before it overwrites, so you can stop a mistake:
$ mv -i new.txt final.txt
mv: overwrite 'final.txt'? n
The -n flag (short for no-clobber) is the quiet version: it skips the move if the destination already exists and never asks, which is handy in scripts where you only want to fill in missing files.
$ mv -n new.txt final.txt # existing final.txt is left untouched
If you pass more than one of -i, -f, and -n, only the last one on the line takes effect. The -f flag (short for force) is the opposite of -i: it overwrites without asking, useful for cancelling an mv that has been aliased to mv -i.
5.2 Seeing What Happens: -v
The -v flag (short for verbose) prints one line per file moved. On a batch of renames this turns a silent operation into a visible list of what actually happened.
$ mv -v draft1.txt draft2.txt final.d/
renamed 'draft1.txt' -> 'final.d/draft1.txt'
renamed 'draft2.txt' -> 'final.d/draft2.txt'
The word renamed in the output is a small clue to what mv really does underneath: even a "move" into another directory is a rename of the file's path.
5.3 Only Move Newer Files: -u
The -u flag (short for update) moves a file only if the source is newer than the destination, or if the destination is missing. It is useful when merging a folder of edits into an existing one without overwriting files you have already updated.
$ mv -u *.txt /shared/docs/ # only files newer than those in docs/ are moved
5.4 Backups Instead of Overwrites: -b
Sometimes you want to overwrite a file but keep the old version just in case. The -b flag (short for backup) renames the existing destination out of the way before writing the new one, adding a ~ to its name by default.
$ mv -b new.conf app.conf
$ ls
app.conf app.conf~ # the old app.conf is now app.conf~
With --backup=numbered you get app.conf.~1~, app.conf.~2~, and so on, so repeated moves never lose an earlier version. This is a lightweight safety habit when replacing configuration files by hand.
6. Advanced Use Cases
6.1 The Directory Trap: Destination Exists or Not
This is the single most confusing thing about moving directories, and it catches everyone at least once. When the destination is a directory name, the result depends on whether that directory already exists.
$ mv src dst # dst does NOT exist: src is renamed to dst
$ mv src dst # dst DOES exist: src is moved INSIDE dst
# giving dst/src
Run the same command in two different situations and you get two different layouts. If dst does not exist, src simply becomes dst. If dst already exists as a directory, src is moved inside it, producing dst/src. When a script mysteriously buries a folder one level too deep, this rule is almost always why.
To force mv to treat the destination as a plain name and never move "into" it, use -T (short for no-target-directory):
$ mv -T src dst # always rename src to dst, never dst/src
The mirror image is -t (short for target-directory), which names the destination directory up front so every other argument is a source. This is essential when building commands with find and xargs, where the directory must come first:
$ find . -name '*.log' -print0 | xargs -0 mv -t /var/log/archive/
6.2 The Trailing-Slash Detail: --strip-trailing-slashes
A trailing slash usually signals "this is a directory". Shell tab-completion often adds one automatically. But a stray slash on a source name can change how mv behaves, especially with symbolic links to directories. The --strip-trailing-slashes option removes any trailing slashes from the source arguments so they are treated as plain names.
$ mv --strip-trailing-slashes linkdir/ newname
You will rarely need this by hand, but it is worth knowing it exists when a scripted mv behaves oddly on names that a completion added a slash to.
6.3 Moving Is Renaming, So Permissions Come Along
Because a same-filesystem move never creates a new file, the file keeps everything: its permissions, owner, timestamps, extended attributes, and inode number stay exactly as they were. There is no -p flag on mv as there is on cp, and none is needed, because nothing is being recreated. The moment mv crosses to another filesystem, though, it must create a new file at the destination, and then it works hard to reproduce those attributes on the copy before deleting the original.
This is why the inode number, which you can see with ls -i, survives a rename on the same disk but changes after a cross-disk move: in the first case it is the same file, and in the second it is a new one.
6.4 Who Is Allowed to Move a File
Because a move edits directory entries rather than the file itself, the permission that matters lives on the directories, not the file. To rename or move a file you need write and execute permission on the source directory, and on the destination directory too. You do not need to own the file, and you do not even need permission to read or write its contents. This surprises many newcomers.
$ ls -l
-rw-r--r-- 1 root root 42 Jul 7 10:00 owned-by-root.txt
$ mv owned-by-root.txt renamed.txt # works: you have write access to the directory
The one exception is a directory with the sticky bit set, such as /tmp. There, only a file's owner (or root) may rename or remove it, which is exactly what stops users on a shared system from moving each other's files out of /tmp.
6.5 Moving a Symbolic Link
When the source is a symbolic link, mv moves the link itself, not the file it points to. The target file stays exactly where it is, and the link simply gets a new name or location while still pointing at the same path.
$ mv mylink newlink # the link is renamed; its target is untouched
Note that a symlink stores its target as a path, not as an inode. If that path was relative, moving the link to another directory can leave it pointing at nothing, because the relative path is now resolved from a different place.
Back to top7. Something Most Users Do Not Know
7.1 A Rename Is Atomic, and That Makes It a Safety Tool
Here is the genuinely useful secret. On the same filesystem, rename() is atomic: from the point of view of any other program, the destination name switches from the old file to the new one in a single instant, with no moment where it is missing, half-written, or empty. If the power fails during the operation, you are left with either the old file or the new file, never a broken mixture.
This is the standard trick for updating an important file safely. Instead of writing directly over config.yaml, where a crash mid-write would leave it truncated, you write to a temporary file in the same directory and then rename it into place:
$ vim config.yaml.new # write the new version to a temp file
$ mv config.yaml.new config.yaml # atomic swap: readers see old OR new, never half
Every reader of config.yaml either sees the complete old file or the complete new one. Countless programs, from text editors to databases, save your work exactly this way. It only works when the temporary file is on the same filesystem as the target, because only then is the rename atomic.
An atomic rename is why "write a temp file, then
mvit over the real one" is the safe way to update any file that other programs might be reading at the same time.
7.2 A Move Across Disks Is a Copy Plus a Delete
People treat every mv as instant and safe, but that is only true within one filesystem. The moment the source and destination live on different disks, partitions, or mounts, mv cannot rename anything. It falls back to reading every byte, writing it to the new location, and then deleting the original, which is exactly what cp does plus an rm.
This changes the risk completely. A cross-disk move of a large file takes real time and, crucially, is not atomic. If it is interrupted halfway, the copy at the destination is incomplete while the original may already be partly processed. This is why an interrupted mv between two disks can be more dangerous than an interrupted cp, and why for big transfers between machines or mounts many administrators copy first, verify, and only then delete the source by hand.
If you are unsure whether a move will be an instant rename or a slow copy, you can check where each path lives before you run it. df -T shows the filesystem and its type for a given path, and stat -c %m prints the mount point a file belongs to. When two paths report the same mount point, a move between them is a rename; when they differ, it is a copy plus a delete.
$ df -T report.txt /mnt/backup/
Filesystem Type ... Mounted on
/dev/sda1 ext4 ... /
/dev/sdb1 ext4 ... /mnt/backup # different mount = copy + delete
7.3 There Is No Undo, and No Trash Can
The famous danger of mv is at the destination: mv a b destroys whatever b was, with no confirmation and no trash can. There is no undo. The original file b pointed to is simply forgotten, and its data will be reused by the system in time.
There is a subtler trap too. Moving a file onto itself is caught and refused:
$ mv a a
mv: 'a' and 'a' are the same file
Yet the shell can hide danger from mv. A wildcard like mv * archive/ in a folder that also contains a file named archive (not a directory) will try to move everything onto that one name, overwriting file after file. When you move with wildcards, look closely at what the * actually expands to first.
A related trap comes from filenames that begin with a dash. A file called -file.txt looks exactly like an option to mv, so the command reads it as a flag and fails with a confusing error. The fix is the -- marker, which tells mv that everything after it is a filename, not an option:
$ mv -- -file.txt archive/ # everything after -- is treated as a name
$ mv ./-file.txt archive/ # or hide the dash behind a ./ path
7.4 Knowing Where mv Stops
Part of expertise is knowing when a different tool fits better. mv is perfect for a one-off rename or a local move. Beyond that, others take over.
| Need | Use | Why |
|---|---|---|
| Rename many files by a pattern | rename / mmv |
Applies a rule to hundreds of names at once, which mv cannot do |
| Move to another machine | rsync / scp |
Copies over the network with SSH; add --remove-source-files to mimic a move |
| Move huge trees between disks safely | rsync |
Can resume after an interruption and verify before you delete the source |
| Keep the original in place | cp |
Duplicates the data instead of moving the name |
A common surprise is that mv cannot rename in bulk. mv *.txt *.md does not do what you might hope; the shell expands the wildcards before mv ever runs, and mv just sees a long list of .txt files with one confusing final argument. For pattern renames, reach for the rename utility. Learn mv first anyway: it is on every machine you will ever log in to, including a rescue shell, and understanding rename versus copy is the foundation the other tools build on.
8. Best Practices
- Assume the destination will be overwritten. Before
mv a b, ask whatbholds now. There is no undo. Use-iwhen working by hand and you are unsure. - Use "temp file then
mv" to update important files. Write the new version alongside the original and rename it into place; the atomic swap means readers never see a half-written file. - Watch the directory-exists trap. With
mv src dst, the result differs depending on whetherdstexists. Use-Twhen you mean "rename to exactly this name". - Add a trailing slash to a destination directory.
mv file dir/fails loudly ifdiris missing, instead of silently renamingfiletodir. - Copy, verify, then delete for cross-disk moves. A move between filesystems is a non-atomic copy plus delete; for large or important data, prefer
rsyncand remove the source only once you have checked the result. - Reach for the manual without hesitation. The habit that separates beginners from professionals is typing
man mvthe moment a question comes up.
$ man mv # the full manual page
$ mv --help # a quick flag summary (GNU)
$ info coreutils 'mv invocation' # the verbose GNU manual
Back to top9. Common Mistakes
9.1 Three Common Myths
| Myth | Reality |
|---|---|
"mv always moves the data." |
On the same filesystem it moves only the name; the data never leaves its spot. It copies data only across filesystems. |
"mv asks before overwriting." |
It does not. By default it overwrites silently. Add -i or -n for safety. |
"mv *.txt *.bak renames every file." |
The shell expands the wildcards first, so this fails. Use the rename utility for pattern renames. |
9.2 Other Traps to Avoid
- Overwriting without noticing.
mv new importantdestroysimportantwith no warning. There is no trash and no undo. - The directory-nesting surprise. Moving
srcinto an existingdstgivesdst/src, not a renameddst. Use-Tto force a plain rename. - Trusting a cross-disk move to be instant and safe. Between filesystems,
mvcopies then deletes; an interruption can leave you with an incomplete file at the destination. - Expecting metadata trouble on a local move. There is none; permissions, owner, and timestamps all survive a same-disk rename because it is the same file.
- Moving over a network mount and assuming a rename. An NFS or other remote mount is a different filesystem, so it is a full copy-and-delete, not a quick name change.
- Filenames that start with a dash.
mv -file.txt dir/is read as options and fails. Put--before the names, or prefix a path such as./-file.txt.
10. Summary
The mv command looks like it does nothing, and on the same disk that is nearly true, which is exactly what makes it such a clean lesson in how Linux separates a file from its name.
mvis short for "move". It renames a file or moves it to another place; both are the same operation, changing where a name points.- On one filesystem it moves only the name, using an atomic
rename(), so moving a huge file or a whole directory is instant and needs no-r. - Across filesystems it cannot rename, so it copies every byte and deletes the original, which takes time and is not atomic.
- The last argument is the destination. Moving into an existing directory keeps the filename; moving several files needs the last argument to be a directory.
- Whether the destination directory already exists changes where the file lands; use
-Tto force a plain rename and-tto name the target directory first. -iasks before overwriting,-nskips existing files,-fforces,-vshows progress,-bkeeps a backup,-umoves only newer files.- Because a rename is atomic, "write a temp file, then
mvit over the target" is the safe way to update a file other programs are reading. - The permission to move a file lives on the directories, not the file: with write access to a folder you can move a file you do not own, unless the sticky bit (as on
/tmp) forbids it. - There is no undo and no trash can;
mv a bdestroys whateverbwas, silently. - Know where
mvstops:renamefor pattern renames,rsyncfor safe cross-disk or remote moves,cpto keep the original. - When in doubt, type
man mv.
This is the quick reference worth keeping:
mv a b rename a to b (overwrites b silently)
mv a b c dir/ move several files into a directory
mv dir dst/ move a whole directory (no -r needed)
mv -T src dst rename src to dst, never dst/src
mv -t dir/ a b c name the target directory first
mv -i a b ask before overwriting b
mv -n a b skip if b already exists
mv -b a b back up the old b as b~ before overwriting
mv -u a b move only if a is newer than b
mv -- -x.txt dir/ move a file whose name starts with a dash
mv tmp real the atomic-swap trick for safe file updates
Small commands like mv hide a surprising amount of how Linux is built, and a single careless move can undo hours of work with no way back. If your servers matter and you want them maintained by someone who understands what is really happening underneath, that is exactly the kind of work I enjoy helping with.


Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.


