Moving and Renaming (mv)
The mv command is how you move files and directories from one location to another on Linux — and, because Linux has no separate “rename” command, it is also how you rename things. Under the hood, moving a file within the same filesystem and renaming a file are literally the same operation: both just change where a filename points. Understanding that fact is the key to understanding mv, its speed, and its few sharp edges.
Overview / How it works
Every file on a Linux filesystem is really two things: the file’s actual data (stored in a structure called an inode, which holds the file’s metadata and pointers to its data blocks), and a directory entry — a name that points to an inode number. A directory is essentially a table mapping names to inode numbers.
When you run mv oldname.txt newname.txt and both paths are on the same filesystem, the kernel does not touch the file’s data at all. It performs a single rename() system call: it removes the directory entry oldname.txt, and adds (or replaces) a directory entry newname.txt that points at the exact same inode. This is why renaming or moving a 50 GB file within the same partition is instantaneous — no bytes are copied, only a table entry changes. It’s also why the operation is atomic: at no point does the file briefly “not exist,” so other processes never observe a half-moved state.
When the source and destination are on different filesystems (for example, moving from your root partition / to a mounted USB drive, or across two different mounted volumes), a single rename() is impossible because inode numbers are only meaningful within one filesystem. In that case mv transparently falls back to copying the file’s data to the new location and then deleting the original. This is slower and, unlike a same-filesystem move, not instantaneous or atomic — if the process is interrupted partway, you can end up with a partial copy at the destination and the original still present (or vice versa).
mv also has a dual personality depending on its destination argument. If the destination does not exist, mv treats it as the new name for the source (a rename). If the destination is an existing directory, mv moves the source into that directory, keeping its original filename unless you explicitly type a new one. This dual behavior is the single most common source of confusion for beginners, so pay close attention to it in the examples below.
Syntax
mv [OPTIONS] SOURCE DESTINATION
mv [OPTIONS] SOURCE... DIRECTORY
The first form moves or renames a single item. The second form moves one or more items into an existing directory. Common options:
| Flag | Meaning |
|---|---|
-i |
Interactive — prompt before overwriting an existing destination file. |
-n |
No-clobber — never overwrite an existing destination file (silently skips it). |
-v |
Verbose — print each source/destination pair as it’s moved. |
-b |
Backup — before overwriting a destination, rename the existing file with a ~ suffix. |
-u |
Update — only move when the source is newer than an existing destination, or the destination is missing. |
-f |
Force — overwrite without prompting, even if permissions would normally ask (overrides an earlier -i). |
-T |
Treat destination as a normal file, not a directory (useful for renaming a directory when a directory of the target name already exists). |
-- |
End of options — treat everything after this as a filename (useful if a filename starts with -). |
Examples
Example 1: Renaming a file
mv notes.txt project_notes.txt
Output:
(no output on success)
Since project_notes.txt did not already exist, mv simply renamed notes.txt in place. mv is silent on success by default, following the Unix convention that no news is good news.
Example 2: Moving a file into a directory
mv ~/Downloads/invoice_march.pdf ~/Documents/invoices/
Output:
(no output on success)
Because ~/Documents/invoices/ already exists as a directory, mv moved the file into it, keeping the name invoice_march.pdf. If that trailing directory did not exist, mv would instead try to create a file literally named invoices containing the PDF’s contents — which is almost never what you want.
Example 3: Moving multiple files at once, verbosely
mv -v /var/log/app/*.log /var/log/app/archive/
Output:
renamed '/var/log/app/access.log' -> '/var/log/app/archive/access.log'
renamed '/var/log/app/error.log' -> '/var/log/app/archive/error.log'
The shell expands the glob *.log into a list of matching files before mv even runs, so this is equivalent to listing each log file individually. Because the final argument is a directory, every matched file is moved into it. The -v flag prints each move as confirmation, which is invaluable when scripting.
Example 4: Renaming a file while moving it, safely
mv -i ~/scripts/backup.sh ~/scripts/archived/backup_2026.sh
Output:
mv: overwrite '/home/user/scripts/archived/backup_2026.sh'?
Here the destination is a full new filename inside an existing directory, so mv both relocates and renames the file in one step. Because a file with that exact destination name already existed, -i made mv pause and ask for confirmation instead of silently overwriting it — typing y proceeds, anything else cancels.
How it works step by step
Walking through mv report.txt ~/archive/report.txt when both paths are on the same disk partition:
- The shell resolves both paths (expanding
~to your home directory) and passes them to themvbinary as two arguments. mvchecks whether the destination exists and whether it is a directory or a plain file, which determines whether this is a rename or a move-into.- If a destination file already exists and no safety flag like
-i/-nwas given,mvwill overwrite it without asking — this is the default and it is destructive. mvcalls therename()system call with the old and new paths. The kernel updates the directory entry atomically: the inode number that used to answer toreport.txtnow answers to~/archive/report.txt.- No file data is read or written, so the operation completes in constant time regardless of file size, as long as source and destination share a filesystem.
If the destination is on a different filesystem, step 4 instead becomes: read the source file’s data and write a full copy at the destination, then delete the original source file — effectively a manual cp followed by rm, performed for you.
Common Mistakes
Mistake 1: Overwriting a file by accident
# Wrong: silently destroys the existing config.yaml
mv config_new.yaml config.yaml
By default mv never asks before overwriting an existing destination file — the old config.yaml is gone the instant this runs, with no trash bin to recover it from. Always use -i (or -n if you’d rather skip than prompt) when the destination might already exist:
mv -i config_new.yaml config.yaml
Mistake 2: Trailing slash typo turning a move into an accidental rename
# Wrong: if 'backups' does not exist, this creates a FILE named 'backups'
# containing the contents of report.csv, instead of moving it into a folder
mv report.csv ~/backups
If ~/backups doesn’t exist as a directory, mv treats it as a target filename and renames report.csv to a file called backups. Always confirm the directory exists first (or create it), and consider using a trailing slash as a sanity signal to yourself:
mkdir -p ~/backups
mv report.csv ~/backups/
Mistake 3: Unquoted variables with spaces or globs
# Wrong: word-splits on spaces in the filename, mv sees multiple arguments
file="Q1 Report.docx"
mv $file ~/Documents/
Without quotes, Bash splits $file on whitespace before mv ever sees it, so mv receives Q1 and Report.docx as two separate arguments instead of one filename — this usually fails with “No such file or directory” or moves the wrong thing. Always quote variable expansions:
file="Q1 Report.docx"
mv "$file" ~/Documents/
Best Practices
- Default to
mv -iin interactive use (or aliasmvtomv -iin your shell config) so you get a warning before any overwrite. - In scripts, prefer
-n(no-clobber) over-iso the script doesn’t hang waiting for input it will never receive. - Always quote path and variable arguments —
mv "$src" "$dest"— to survive spaces and special characters safely. - When moving into a directory, add the trailing slash (
dest/) so a typo in the directory name fails loudly instead of silently creating a same-named file. - Use
-vin scripts that move important files, so logs show exactly what happened. - For anything irreversible or high-stakes, consider
cpthen verify thenrm, rather than a one-shotmv, if you want an extra safety window. - Remember
mvacross filesystems is a copy-then-delete: for very large files, a stray power loss mid-move can leave things in a partial state — for critical cross-filesystem transfers, verify checksums afterward.
Practice Exercises
- Create a file called
draft.txt, then rename it tofinal.txtusing a singlemvcommand. Confirm withlsthatdraft.txtno longer exists. - Create a directory
~/practice/incomingand three files nameda.log,b.log,c.login your home directory. Move all three intoincomingin one command, using-vso you can see each move confirmed. - Create two files with the same name in different directories (e.g.
~/practice/notes.txtand~/practice/incoming/notes.txt). Try moving the first on top of the second usingmv -iand observe the prompt; answernto cancel, then try again with-nand confirm the file is left untouched.
Summary
mvboth moves and renames files/directories — Linux has no separate rename command.- On the same filesystem,
mvis a single atomicrename()system call that just updates a directory entry — no data is copied, so it’s instant regardless of file size. - Across filesystems,
mvfalls back to copy-then-delete, which is slower and not atomic. - If the destination is an existing directory, the source is moved into it; if not, the destination becomes the new name — this distinction causes most beginner mistakes.
mvoverwrites existing destination files silently by default — use-ior-nto protect yourself.- Always quote variables and paths (
"$file") to avoid word-splitting on spaces.
